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


     题目大意:这是一道交互题。给你一个长度为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
    ",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; 
    }
  • 相关阅读:
    一个故事告诉你,数据分析如何给企业带来价值
    【CS231n】斯坦福大学李飞飞视觉识别课程笔记(九):最优化笔记(上)
    区块链P2P网络详细讲解
    互联网协议入门
    BitTorrent DHT 协议中文
    基于侧链的P2P网络设计
    【转】P2P-BT对端管理协议
    P2P网络与BitTorrent技术简介
    【COCOS2DX-LUA 脚本开发之四】使用tolua++编译pk创建自定义类
    爱创课堂每日一题第五十四天- 列举IE 与其他浏览器不一样的特性?
  • 原文地址:https://www.cnblogs.com/clno1/p/10420899.html
Copyright © 2020-2023  润新知