http://codeforces.com/group/NVaJtLaLjS/contest/236426/problem/G
题意:
圣诞老人的键盘有些键装反了,就是说两个键之间装错了位置。
如a和b键装反了,那么按下aaab,其实是输入bbba。
现在按下s字符串,得到t字符串,问有多少对按键装反了,这些按键是什么。
如果出现了按下aaa得到bcd或者按下bcd得到aaa这种不可能的情况,输出-1。
输入:
两个字符串,字符串最长1000,全为小写英文字母。
示例:
Input:
helloworld
ehoolwlroz
Output:
3 h e l o d z
Input:
hastalavistababy
hastalavistababy
Output:
0
Input:
merrychristmas
christmasmerry
Output:
-1
本来非常容易的一道题,因为我看漏了条件,活活WA了10次,最后发现题目指明是两个按键之间装反了。
就是按下a得到b,那么在ab键装反的情况下,按下b会得到a。
我原本以为会有qwe和weq这样的错位关系……
知道题意后就非常简单了,建立映射关系,表明哪两个键之间是装反的。
首先声明映射数组:
char map[666]={0};
一开始里面的映射都是空的。从第一个字母开始同时检查两个字符串:
如果这两个(同一个)字母在数组中没有映射,那么建立映射,即把字符值赋值给代表对方的元素。然后计数+1。
比如a/b映射,那么:
map[ 'a' ]='b',map[ 'b' ]='a'; count++;
请把这里的'a''b'换做你使用的变量,比如s[i],t[i]。
如果这两个字母中至少一个已经有了映射,那么检查这两个字母是否符合这种映射关系;
不符合的话,直接输出-1,结束程序。
(一个有映射一个没有映射就会出现这种情况,也就是上面说的按下aaa得到bcd的情况。这种情况直接-1都可以。)
最后输出计数,再遍历映射数组,看到不是映射自己的就输出,然后把这两个字母的映射改为映射自己,即表示把按键换回来了,避免重复输出。
比如a/b映射,那么一套for循环:
if( map[ i ]!=(int)i ) { printf("%c %c\n",i,map[i]); map[ map[i] ]=map[i]; map[i]=i; }
代入'a',看看对不对。
这里就不提供代码了。因为不停WA到最终发现看错题意之间把代码改得实在太复杂,实现没有上面这么简单明了。解说已经非常详细,代码请君自行编写。