zoukankan      html  css  js  c++  java
  • toodifficult 题解

    名字听起来十分厉害啊...一道lzz的提交答案题。

    提答题,我们看看题目,给出一个解密程序,叫你加密。

    每个点有一个加密的sample和一些要加密的文本。

    从题目中我们可以得到一些信息:

    image

    加密后一般为8/16个一组,字符集|S|=95。

    那就来看数据吧。

    Data 1

    image

    奥妙重重...overwatch是什么鬼啊

    咦第一行15个字符,加密完120个字符。怕是8位ascii?

    写完一测,样例挂了。

    然后去完那个解密器,随手输了8位,invalid output?但是sample确实是1位=>8位啊。

    后面想想,可能只是一个映射,不一定是ascii,反正有sample。我真是傻逼

    测了测sample,发现里面95个字符都有,然后就没有了。

    #include <iostream>
    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    #include <time.h>
    #include <stdlib.h>
    #include <string>
    #include <vector>
    #include <fstream>
    #include <set>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <sstream>
    #include <stack>
    #include <iomanip>
    using namespace std;
    map<char,string> mpp;
    int main()
    {
        ifstream fin("toodifficult1_simple.in");
        ifstream fin2("toodifficult1_simple.out");
        string s,s2;
        while(getline(fin,s))
        {
            getline(fin2,s2);
            int j=0;
            for(int i=0;i<s.length();i++)
            {
                string rp;
                for(int k=j;k<j+8;k++) rp.push_back(s2[k]);
                j+=8;
                mpp[s[i]]=rp;
            }
        }
        ifstream qwq("toodifficult1.in");
        freopen("toodifficult1.out","w",stdout);
        while(getline(qwq,s))
        {
            for(int i=0;i<s.length();i++) cout<<mpp[s[i]];
            putchar(10);
        }
    }

    Data 2

    image

    咦那个aaaaa...aaaa怎么看起来这么鬼畜啊...怕是有什么肮脏的****。

    似乎是二进制减一?数一数,似乎是16位一分割。

    image

    咦那个一串一串的16个1是啥啊...懵逼

    然后我们拉到第一行最后...咦最后有一大坨1,数一数好像是25*16个1...

    excited!似乎和字母有关。

    好像这里思路就中断了...玩玩那个解密程序好了。

    input:400个1 output:""

    input:15个0+401个1 output:"a"

    嗯这很正常。

    input:16个1+15个0+385个1 output:"b"

    咦,shenmegui,难道这是分割字母的?

    input:15个0+17个1+15个0+385个1 output:Invalid

    哦好像是下标?

    input:15个0+17个1+14个0+1+0+384个1 output:"ab"

    input:14个0+1+0+16个1+15个0+385个1 output:"ba"

    后缀数组!不同开头的后缀中间插16个1!

    那么我们只要写一个暴力就行了233

    #include <iostream>
    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    #include <time.h>
    #include <algorithm>
    #include <stdlib.h>
    #include <string>
    using namespace std;
    char s[233333];
    int rp[233333];
    bool cmp(int a,int b)
    {
        for(int x=0;;++x)
        {
            if(s[a+x]!=s[b+x]) return s[a+x]<s[b+x];
        }
        return 0;
    }
    int main()
    {
        freopen("toodifficult2.in","r",stdin);
        freopen("toodifficult2.out","w",stdout);
        string str;
        while(getline(cin,str))
        {
            strcpy(s,str.c_str());
            int n=str.size();
            for(int i=0;i<n;i++) rp[i]=i;
            sort(rp,rp+n,cmp);
            int cur='a';
            for(int i=0;i<n;i++)
            {
                int r=rp[i]+1,p=s[rp[i]];
                while(cur<p) printf("1111111111111111"), ++cur;
                int rs[16];
                for(int k=0;k<16;k++) rs[k]=r%2, r/=2;
                for(int k=15;k>=0;k--) putchar(rs[k]+48);
            }
            while(cur<'z') printf("1111111111111111"), ++cur;
            putchar(10);
        }
    }

    Data 3

    image

    这输入是什么卵子啊...怎么这么乱啊...似乎是随机字符?

    咦输出好像是64位啊...这是啥啊...是个整数?

    咦输入可能也是整数?95进制?题目里还给了字符集?真刺激

    S="a bcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,./?;:'"<>[]{}()|-_=+*&^%$#@!`~"

    试试95进制然后转二进制?看了看好像不太像。

    然后就gg了。(接下来去看了题解

    woc要把这些大数分解质因数!pollard-rho!

    然后把小的因数放在前面输出就行了。

    #include <iostream>
    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    #include <time.h>
    #include <stdlib.h>
    #include <string>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <sstream>
    #include <stack>
    #include <iomanip>
    using namespace std;
    char gg[2333];
    string S="a bcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,./\?;:'"<>[]{}()|-_=+*&^%$#@!`~";
    typedef long long ll;
    ll mul(ll a,ll b,ll n)
    {
        ll ans=0;
        while(b)
        {
            if(b&1) ans=ans+a, ans%=n;
            a=(a+a)%n; b>>=1;
        }
        return ans;
    }
    ll f(ll x,ll n)
    {
        return (mul(x,x,n)+1)%n;
    }
    ll gcd(ll a,ll b) {if(a<0) a=-a; if(b<0) b=-b; return b?gcd(b,a%b):a;}
    ll rho(ll n)
    {
        ll x=2, y=2, p=1;
        while(p==1)
        {
            x=f(x,n);
            y=f(f(y,n),n);
            p=gcd(x-y,n);
        }
        return p;
    }
    int main()
    {
        freopen("toodifficult3.in","r",stdin);
        freopen("toodifficult3.out","w",stdout);
        for(int i=0;i<S.size();i++) gg[S[i]]=i;
        string s;
        while(getline(cin,s))
        {
            long long r=0;
            for(int i=0;i<s.size();i++) r=r*95+gg[s[i]];
            ll a=rho(r),b=r/a;
            if(a>b) swap(a,b);
            int rs[32];
            for(int k=0;k<32;k++) rs[k]=a%2, a/=2;
            for(int k=31;k>=0;k--) putchar(rs[k]+48);
            for(int k=0;k<32;k++) rs[k]=b%2, b/=2;
            for(int k=31;k>=0;k--) putchar(rs[k]+48);
            putchar(10);
        }
    }

    Data 4

    太毒了...待补

    Data 5

    image

    喂出题人!MD5是什么鬼啊!不是吧

    咦说好MD5呢怎么sample的out里面全是10010啥的...

    然后去玩checker,发现可以输入字符串啊!然后checker确实会返回正确的字符串md5。

    咦,这01串怕是有什么交易...咦第一个点输出好像长得差不多...我把所有东西压成一行当第一个点丢给checker解密好了。

    image

    真刺激,以下是解密后的全文(人工换行):

    As you know, it's too difficult to solve this case.
    So I will give you some problems, you just need to answer them.
    All of the answers of these problems only consist of lower-case letters and numbers.
    No.1 What do I like to play?
    No.2 There is a poem including these words "gouliguojiashengsiyi", and then?
    No.3 Who wrote this poem?
    We often call the Mobius function mu(n).f(n)=sum (i=1 to n) mu(i).
    No.4 Please work out the minimum of f(n) when n belongs to [1,10^9].
    No.5 Please work out the maximum of f(n) when n belongs to [1,10^9].
    No.6 The last problems may be the most difficult problem of this contest.
    Can you work out C(6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666,
    2333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333) mod (1e100+7) ?

    咦怎么只有6个问题...哦原来4和5两个问题分比较多。

    No.1 overwatch(233

    No.2 qiyinhuofubiquzhi(excited

    No.3 jiangzemin(吃枣药丸

    然后丢进checker一测,好像答案不对?md还要用第一题的那个加密程序啊

    然后发现No.3 还是不对...后面想想好像是linzexu...(果然姿势水平不够高

    接下来两个问题是什么卵子啊...梅滕斯函数的极值?我**怎么知道啊

    暴力硬肛的话...除了空间都没什么问题。

    额其实我们可以开三个bitset,每个10^9存质数和mu...

    然后这样是过不了编译的...但是我们可以new...大概分配了4G内存,然后跑线筛,跑了200s,答案跑出来了...跑得电脑黑汗水流

    image

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <algorithm>
    #include <iomanip>
    #include <time.h>
    #include <map> 
    #include <bitset>
    using namespace std;
    #define MAXN 1000000000
    int *ps,pn=0;
    bitset<10000000001> np;
    bitset<10000000001> *hm_;
    bitset<10000000001> *ms_;
    void shai()
    {
        long long qzh=1;
        bitset<10000000001>&hm=*hm_;
        bitset<10000000001>&ms=*ms_;
        np[1]=1; hm[1]=1; ms[1]=1;
        long long maxn=1, minn=1;
        for(int i=2;i<=MAXN;i++)
        {
            if(!np[i]) {ps[++pn]=i; hm[i]=1; ms[i]=0;}
            for(int j=1;j<=pn&&ps[j]*i<=MAXN;j++)
            {
                int p=ps[j]*i; np[p]=1;
                if(i%ps[j]) hm[p]=hm[i], ms[p]=!ms[i];
                else {hm[p]=0; break;}
            }
            if(hm[i]) qzh+=(ms[i])?1:-1;
            maxn=max(maxn,qzh);
            minn=min(minn,qzh);
            if(i&131071);else cout<<i<<","<<minn<<","<<maxn<<" left"<<(1000000000*(clock()/(double)i)-clock())/1000.0<<"s
    ";
        }
        cout<<minn<<","<<maxn<<"
    ";
    }
    #define S2 80000000
    int main()
    {
        cout<<"准备分配"<<(sizeof(np)*3+sizeof(int)*S2)/1024.0/1024.0/1024.0<<"GB内存!
    ";
        ps=new int[S2];
        cout<<"进度33%
    ";
        hm_=new bitset<10000000001>();
        cout<<"进度66%
    ";
        ms_=new bitset<10000000001>();
        cout<<"进度100%
    ";
        shai();
    }

    接下来No.6的话...woc这...如果电脑上没有python的话还是算了吧QAQ

    ......答案果然是no。

    最后输出用的东西

    #include <iostream>
    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    #include <time.h>
    #include <stdlib.h>
    #include <string>
    #include <vector>
    #include <fstream>
    #include <set>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <sstream>
    #include <stack>
    #include <iomanip>
    using namespace std;
    map<char,string> mpp;
    int main()
    {
        ifstream fin("toodifficult1_simple.in");
        ifstream fin2("toodifficult1_simple.out");
        string s,s2;
        while(getline(fin,s))
        {
            getline(fin2,s2);
            int j=0;
            for(int i=0;i<s.length();i++)
            {
                string rp;
                for(int k=j;k<j+8;k++) rp.push_back(s2[k]);
                j+=8;
                mpp[s[i]]=rp;
            }
        }
        ifstream qwq("toodifficult5_u.out");
        freopen("toodifficult5.out","w",stdout);
        while(getline(qwq,s))
        {
            for(int i=0;i<s.length();i++) cout<<mpp[s[i]];
            putchar(10);
        }
    }

    Q:不行啊,考场机子一共就不到4G内存,那个点怎么做啊wtf

    A:暴搜啊...不是给了checker吗...反正答案估计就不是很大...随便搜搜

    (UPD:刚才测了测暴搜,跑得十分的慢啊,就不贴上来了...而且还时不时出个bug啥的...不过如果在程序中直接内嵌一个算md5的代码应该会快很多把)

    然后这样就有80分啦23333这提答真是刺激啊

  • 相关阅读:
    output (Elements) – HTML 中文开发手册
    JavaSE IO类层次关系和Java IO流的用法总结
    PHP attributes() 函数
    math_errhandling (Numerics) – C 中文开发手册
    C while 循环
    HTML <a> hreflang 属性
    static_assert (Error handling) – C 中文开发手册
    C 嵌套 switch 语句
    HTML DOM Input Time name 属性
    Bootstrap 弹出框
  • 原文地址:https://www.cnblogs.com/zzqsblog/p/5667361.html
Copyright © 2011-2022 走看看