Educational Codeforces Round 60 (Rated for Div. 2) E. Decypher the String 交互 思维

标题

题目大意,给你一个长度为n的加密后的串,加密方式是交换至多n-1次任意两个字符,要求3次询问后得到原有串,每次可以任意询问一个串加密后的结果。

将整个串进行划分处理,三次询问分块大小分别为26*26*26、26*26、26。
首先询问一个aaaa…bbbb…cccc…dddd…zzzz…每个字母都有26*26个,根据结果可以得到每个位置的字符初始位置在哪个分块,可以将字符确定在分块范围内即26*26。
再次询问一个还是包含各种字母的串,每个字母26个,结合第一次的结果可以得到每个位置的字符原始在哪个26大小的分块。
第三次询问为abcd…xyzabcd…,原理同第二次询问可以将范围缩小到具体位置。

AC代码

#include <stdio.h>
#include <bits/stdc++.h>
#define fst first
#define sed second
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 1e4 + 10;
char s[MAXN], t[MAXN], ask[3][MAXN];

char code(int i, int j)
{
	while (i--)
		j /= 26;
	return 'a' + j % 26;
}
int pos(int i)
{
	int k = 0;
	for (int j = 0; j < 3; j++)
		k = k * 26 + ask[j][i] - 'a';
	return k;
}
int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin);
#endif
	scanf("%s", t);
	int n = strlen(t);
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < n; j++)
			ask[i][j] = code(2 - i, j);
		printf("? %s\n", ask[i]);
		fflush(stdout);
		scanf("%s", ask[i]);
	}
	for (int i = 0; i < n; i++)
		s[pos(i)] = t[i];
	printf("! %s\n", s);
	fflush(stdout);

	return 0;
}

猜你喜欢

转载自blog.csdn.net/CaprYang/article/details/87869928