1. 程式人生 > >Educational Codeforces Round 60 (Rated for Div. 2) E. Decypher the String

Educational Codeforces Round 60 (Rated for Div. 2) E. Decypher the String

bsp 位置 esp 解決 nal clas div cypher cati

題目大意:這是一道交互題。給你一個長度為n的字符串,這個字符串是經過規則變換的,題目不告訴你變換規則,但是允許你提問3次:每次提問你給出一個長度為n的字符串,程序會返回按變換規則變換後的字符串,提問3次後你需要猜出這個字符串。解法是學習https://blog.csdn.net/baiyifeifei/article/details/87807822 這個博主的,借用了進制的思想非常巧妙。

解法:對於某個位置的來源位置我們設為x,因為26*26*26>10000,那麽x可以唯一表示為x=a*26*26+b*26+c。那麽我們只要想辦法求出a,b,c就能得到它的來源位置。

那麽怎麽利用三次詢問求a,b,c?我們首先構造(26*26個a) (26*26個b) (26*26個c)......(26*26個z),設此位置變換後的字符為c[0],那麽a=c[0]-‘a‘(可以理解為a=x/(26*26)=c[0]-‘a‘)。道理類似的我們下一次構造(26個a) (26個b) (26個c) ......(26個d)的字符串讓程序變換,此時變換後的字符為c[1],那麽b=c[1]-‘a‘(可以理解為b=x%(26*26) /26=(b*26+c)/26=c[1]-‘a‘),這裏的b可能有點兒難理解,為什麽是這樣得到的c[1]就是(b*26+c)/26?因為前一個詢問我們已經確定x在a這一個(26*26)的大塊裏面了,那麽我們只需要考慮這個大塊,把這個大塊再細分為26塊看看返回什麽值就能知道x在a這個大塊的哪一個小塊b裏面。道理類似的最後構造(abc..z)(abc..z)...(abc..z)得到c=c[2]-‘a‘。

那麽我們就得到該位置的來源是a*26*26+b*26+c,問題得到解決。

如果還是感覺難以理解,可以看看代碼再仔細想想:

#include<bits/stdc++.h>
using namespace std;
const int N=10000+10;
int n;
char s[N],q[3][N],g[3][N],ans[N];

int main()
{
    scanf("%s",s);
    n=strlen(s);
    for (int i=0;i<n;i++) {
        q[0][i]=(i/(26*26)%26+a);
        q[1][i]=(i/26
%26+a); q[2][i]=(i%26+a); } for (int i=0;i<3;i++) { printf("? %s\n",q[i]); fflush(stdout); scanf("%s",g[i]); } for (int i=0;i<n;i++) { int tmp=(g[0][i]-a)*26*26+(g[1][i]-a)*26+(g[2][i]-a); ans[tmp]=s[i]; } printf(
"! %s",ans); return 0; }

Educational Codeforces Round 60 (Rated for Div. 2) E. Decypher the String