链接:http://codeforces.com/contest/527/problem/B
一开始还有有点纠结交换的两个数字的前后顺序,然后我就用了个n*n的。。结果超时了。。
去看了下前几名的代码,自己确实没有想到这样的方法。。
简单来说思路就是,将两个字符串中不相等的字母对取出来,开一个p[26][26]的数组保存,存下这个字母对所占的位置。。遍历每个位置,全部找出来。。然后先看看有没有交叉相等的情况,这种情况要-2 ,遍历p数组,如果没有,再遍历一次,对于每个字母对,遍历26个字母看是否有可以交换并且会使Hamming distance 减少的字母对。。
附上代码
#include<iostream>
#include<cstring>
using namespace std;
char s1[200010],s2[200010];
int p[100][100]; //保存一对序列。。
int main ()
{
int n;
while(cin >> n)
{
cin >> s1;
cin >> s2;
int count = 0;
int ok = 0;
memset(p,0,sizeof(p));
for(int i = 0;i < n;i++)
{
if(s1[i] != s2[i])
{
count++;
if(p[s1[i]-'a'][s2[i]-'a']==0) //这个没有其实也可以在哪个位置不重要主要是最后Hamming distance是多少
p[s1[i]-'a'][s2[i]-'a'] = i+1;
}
}
for(int i = 0;i < 26;i++)
{
for(int j = 0;j < 26;j++)
{
if(p[i][j]!=0 && p[j][i]!=0) //如果刚好交叉相等 比如 a....b
{ // b....a
ok = 1;
count -= 2;
cout << count << endl;
cout << p[i][j] << " "<< p[j][i] << endl;
goto out;
}
}
}
for(int i = 0;i < 26;i++)
{
for(int j = 0;j < 26;j++)
{
if(p[i][j]!=0)
{
for(int k = 0;k < 26;k++)
{
if(p[k][i]!=0 && k!=i) //如果没有交叉相等的 只有 a....b
{ // c....a
ok = 1;
count -= 1;
cout << count << endl;
cout << p[i][j] << " "<< p[k][i] << endl;
goto out;
}
}
}
}
}
out:
if(!ok)
{
cout << count << endl;
cout << -1 << " " << -1 << endl;
}
}
return 0;
}