Educational Codeforces Round 60 E (数学思维)

题目链接

E. Decypher the String

题意:

一道交互题,系统生成了一个字符串 S S ( 26 26 个小写字母组成 l e n < = 1 e 4 len<=1e4 ),并且执行了若干次操作,每次操作交换两个位置的字符,现在给你交换完的串,让你询问不超过 3 3 次得到原来的串,每次询问可以输入一个同样长度由小写字母组成的串,系统返回将该串经过同样操作后的字符串。

思路:

考虑到 26 26 26 > 1 e 4 26*26*26>1e4 所以我们将字符串长度分为 26 26 进制 就只有 3 3 位数,也就是说对于 i = x 26 26 + y 26 + z i=x*26*26+y*26+z ,那么我们对 x , y , z x,y,z 分别建立一个字符串,得到的字符串 s 1 , s 2 , s 3 s1,s2,s3 就对于交换后每一个位置的 x 1 , y 1 , z 1 x1,y1,z1 通过和前面一样的转换就可以得到 i 1 = x 1 26 26 + y 1 26 + z 1 i1=x1*26*26+y1*26+z1 ,就是变换后额位置,那么就可以求出原串了。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N=1e4+10;
string query(string x){
	string temp;
	cout<<"? "<<x<<endl;
	fflush(stdout);
	cin>>temp;
	return temp;
}
int pos[N],ans[N];
string s1[3],s2[3],s;
int main()
{	
	int n;
	cin>>s;n=s.length();
	for(int i=0;i<n;i++){
		s1[2]+=char(i/(26*26)%26+'a');
		s1[1]+=char((i/26)%26+'a');
		s1[0]+=char(i%26+'a');
	}
	for(int i=0;i<3;i++){
		s2[i]=query(s1[i]);
	}
	for(int i=0;i<n;i++){
		pos[i]=((s2[2][i]-'a')*26*26)+((s2[1][i]-'a')*26)+(s2[0][i]-'a');
	}
	cout<<"! ";
	for(int i=0;i<n;i++)ans[pos[i]]=i;
	for(int i=0;i<n;i++)cout<<s[ans[i]];
	cout<<endl;

}

猜你喜欢

转载自blog.csdn.net/qq_40400202/article/details/101694424