[ 题解 ] [ 映射 ] G. Santa Claus and Keyboard Check (待更名)
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到最终发现看错题意之间把代码改得实在太复杂,实现没有上面这么简单明了。解说已经非常详细,代码请君自行编写。
先放一份不断修改的辣鸡实现
1 #include <stdio.h> 2 #include <string.h> 3 4 char Patter[1111]={0}; 5 char Result[1111]={0}; 6 char map[1111]={0}; 7 int answer=0; 8 short mark[1111]={0}; 9 10 int main() 11 { 12 gets(Patter); 13 gets(Result); 14 15 for(int i='a';i<='z';i++) 16 map[i]=i; 17 for(int i=0;Patter[i];i++) 18 { 19 if(mark[ (int)Patter[i] ]==0) 20 { 21 mark[ (int)Patter[i] ]=1; 22 // 23 if(Patter[i]!=Result[i]) 24 { 25 if(map[ (int)Patter[i] ]==(int)Patter[i]) 26 { 27 if( mark[ (int)Result[i] ]==1 && map[ (int)Result[i] ]!=Patter[i] ) 28 { puts("-1"); return 0; } 29 mark[ (int)Result[i] ]=1; 30 map[ (int)Patter[i] ]=Result[i]; 31 map[ (int)Result[i] ]=Patter[i]; 32 answer++; answer++; 33 } 34 else // 35 if(map[ (int)Patter[i] ]!=Result[i]) 36 { puts("-1"); return 0; } 37 } 38 39 } 40 else 41 if(map[ (int)Patter[i] ]!=Result[i]) 42 { puts("-1"); return 0; } 43 } 44 /* 45 for(int i=0;Result[i];i++) 46 { 47 Result[i]=map[ (int)Result[i] ]; 48 } 49 puts(Result); 50 if(strcmp(Patter,Result)!=0) 51 { puts("-1"); return 0; } 52 */ 53 for(int i='a';i<='z';i++) 54 if( map[i]!=i && map[ (int)map[i] ]==i ) 55 { 56 map[i]=i; 57 answer--; 58 } 59 60 printf("%d\n",answer); 61 for(int i='a';i<='z';i++) 62 if(map[i]!=i) 63 printf("%c %c\n",i,map[i]); 64 65 return 0; 66 }