我是没有参加这场比赛的,是在比赛后作的练习。
level 1:因为对于任何的偶数长度的子串,‘o’和‘x’是一样多的。所以'o'和'x'相邻出现的。所以我们只要找到第一个不是‘?’就可以了,下面的话,下一个会和这个不一样,前面的也和这个不一样,‘o’和'x'相间出现。
level 2:a XOR b = c,则 a XOR c = b , b XOR c = a。这样,我们需要找的是一个数x,对于每一个在ciphertexts中出现的c,c XOR x都能在plaintexts中找到相应的值p。这样我们可以得出,如果把每一个在ciphertexts中的c和每一个在plaintexts中的p做XOR运算,这样x出现的次数应该是ciphertexts.size()次。因为每一个ciphertexts中的c c XOR x在plaintexts中都有相应的p,则c XOR p是x,这样x就会出现ciphertexts.size()次。如果在两个集合做XOR运算中出的结果出现的次数小于ciphertexts.size()次,则这个结果不要。
level 3:这道题目中,描述了原来串中每一个character也是不一样的,所以我们可以枚举在这一个可以出现什么字符。字符串的长度和出现的字符总数是一样的。在i中能出现的字符ch,是在各个字符串中,在ch前面出现的字符,都已经在0 到 i - 1中填好了,所以我们选择符合这样情况的最小的ch填入即可。附上代码
class NetworkXMessageRecovery { public: int a[256]; bool b[256]; int sl; string recover(vector <string> messages) { string ret = ""; memset(a , 0 , sizeof(a)); memset(b , 0 , sizeof(b)); sl = 0; for (int i=0 ; i<messages.size() ; i++) { init(messages[i]); } for (int i=0 ; i<sl ; i++) { for (int j='A' ; j<='z' ; j++) { if (b[j] && a[j] == 0) { ret += (char)j; b[j] = false; process(messages , (char)j); break; } } } return ret; } void init(string message) { for (int i=0 ; i<message.length() ; i++) { a[(int)message[i]] += i; if (b[(int)message[i]] == false) { sl++; b[(int)message[i]] = true; } } } void process(vector <string>messages , char ch) { bool flag; for (int i=0 ; i<messages.size() ; i++) { flag = false; for (int j=0 ; j<messages[i].length() ; j++) { if (flag) { a[(int)messages[i][j]]--; } if (messages[i][j] == ch) { flag = true; } } } } };