A,B,C都是水题,D题要注意的是数据范围,开longdouble过了。
着重讲本次的E题,由我的朋友给我详细解释了这道题的思路以及核心代码的讲解,先贴代码
#include<bits/stdc++.h>
using namespace std;
int n, k, dist[2505];
int sum1[200],sum2[200];
string s[2505];
bool t;
int main()
{
cin>>k>>n;
for(int i=1;i<=k;i++)
{
cin>>s[i];
}
bool t=0;
for(int i=0;i<=n;i++)
{
sum1[s[1][i]-'a']++;
if(sum1[s[1][i]-'a']>1)t=1;
}
for(int i=2;i<=k;i++)
{
for(int j=0;j<=n;j++)
{
sum2[s[i][j]-'a']++;
if(s[i][j]!=s[1][j]) dist[i]++;
}
for(int j=0;j<26;j++)
{
if(sum1[j]!=sum2[j])
{
cout<<"-1";
return 0;
}
sum2[j]=0;
}
}
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
int check=1;
for(int z=2;z<=k;z++)
{
int cnt=dist[z];
if(s[1][i] != s[z][i])cnt--;
if(s[1][j] != s[z][j])cnt--;
if(s[1][j] != s[z][i])cnt++;
if(s[1][i] != s[z][j])cnt++;
if(!((cnt==0&&t)||cnt==2))
{
check=0;
break;
}
}
if(check)
{
swap(s[1][i],s[1][j]);
cout <<s[1]<<endl;
return 0;
}
}
}
cout<<-1<<endl;
return 0;
}
本题的思路在于有技巧的暴力,通过对第一行的字符串进行换位,和后面的字符串比较位置差异的个数以及字母的构成是否相同来完成查询,核心代码就在于暴力中的四个一起的if语句,完成对于假设换位后对于原来不同位置以及现在不同位置的个数作出修剪,当剩余不同位置数为2或者0个(且要有相同字母)的时候,交换的操作是成立的。