[UOJ73【WC2015】未来程序] 毒瘤提交答案题

第一次做提交答案题,感受到毒瘤出题人满满的恶意(考场上考这个原地爆炸)

#73. 【WC2015】未来程序

在 2047 年,第 64 届全国青少年信息学奥林匹克冬令营前夕,B君找到了 2015 年,第 32 届冬令营的题目来练习。 他打开了第三题 “未来程序” 这道题目: 本题是一道提交答案题,一共 10 个测试点。 对于每个测试点,你会得到一段程序的源代码和这段程序的输入。你要运行这个程序,并保存这个程序的输出。 遗憾的是这些程序都效率极其地下,无法在比赛的 5 个小时内得到输出。 B君想了一下,决定用 2047 年的计算机来试着运行这个题目,他找到了 2015 年的编译器,并很快得到了结果…… 这时B君从梦中惊醒,发现自己居然在第 32 届冬令营赛场上。之前的一切只是南柯一梦,而自己正需要解决“未来程序”这道题目。 然而B君已经记不清梦中的程序运行的结果了,他试图再次运行这些程序。但是他发现计算机性能比梦里的差多了,程序确实都无法在 55 小时内得到结果。 他需要你的帮助,来得到那些梦中的结果。 本题是一道提交答案题,一共有 10 个测试点。 对于每个测试点,你会得到一段程序的源代码和这段程序的输入。你要运行这个程序,并保存这个程序的输出。 遗憾的是这些程序效率都极其低下,无法在比赛的 55 小时内得到输出。 你需要帮助B君得到这些程序的输出。

题意

简单来说,10个点,给你10个c++暴力程序和10个输入,然后让你看懂这些代码在干什么事情然后中间会有一些奇奇怪怪的东西,写出他不那么暴力的代码之后,用输入跑出这些读入之后提交读出. 太毒瘤了,显然不是准备你考场上做完的,如果遇到了,就尽可能把简单好写,容易看出题意的点写了,不然时间上完全耗不起.

t1

long long 范围a*b%p 考虑到linux直接上python.龟速乘+卡速米似乎也可以.

t2

就是给你a,b,c,然后b=a+b,a=2b-a+c,c=2b-a+c,求n次这样运算之后最后a-2*b+c结果 裸上矩乘.
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define int long long
using namespace std;
int n,p;
int add(int x,int y) { x=(x+y)%p; return x<0?x+p:x; }
int mul(int x,int y) { return 1ll*x*y%p; }
int sub(int x,int y) { x=(x-y)%p; return x<0?x+p:x; }
struct mat{
    int o[4][4];
}A,ans,KO;
mat operator*(mat aa,mat bb) {
    static mat tmp;
    for(int i=1;i<=3;i++) {
        for(int j=1;j<=3;j++) {
            int tp = 0;
            for(int k=1;k<=3;k++) {
                tp = add(tp,mul(aa.o[i][k],bb.o[k][j]));
            }
            tmp.o[i][j] = tp;
        }
    }
    return tmp;
}
void _______() {
    long long i, a, b, c, d;
    a = 1;
    b = 0;
    c = 0;
//  scanf("%lld %lld", &n, &p);
    i = 1;
    while (i <= n) {
        i = i + 1;
        b = a + b;
        a = 2 * b - a + c;
        c = 2 * b - a + c;
        while (a >= p) {
            a -= p;
        }
        while (a < 0) {
            a += p;
        }
        while (b >= p) {
            b -= p;
        }
        while (b < 0) {
            b += p;
        }
        while (c >= p) {
            c -= p;
        }
        while (c < 0) {
            c += p;
        }
    }
    d = a - 2 * b + c;
    while (d >= p) {
        d -= p;
    }
    while (d < 0) {
        d += p;
    }
    cerr<<d<<endl;
}
void KSM(int b) {
    for(;b;b>>=1,A=A*A)
        if(b&1) ans = ans*A;
}
void solve() {
    scanf("%lld%lld",&n,&p);
    ans = A = KO;
    A.o[1][1] = A.o[1][2] = A.o[1][3] = A.o[2][2] = A.o[3][1] = 1;
    A.o[2][1] = 2; ans.o[1][1] = 1;
    KSM(n);
    int d = 0;
    d = add(sub(ans.o[1][1],mul(2,ans.o[1][2])),ans.o[1][3]);
    printf("%lld\n",d);
//  _______();
}

main() {
    freopen("program2.in","r",stdin);
    freopen("./OUT/2.out","w",stdout);
    int T = 10;
    while(T--) solve();
}

t3

自然数幂和,求0次幂,1次幂,2次幂,3次幂,4次幂. 强行背一波公式 $ S_{0}(n) = n+1 $ $ S_{1}(n) = \frac{n*(n+1)}{2} $ $ S_{2}{n} = \frac{n(n+1)(2*n-1)}{6} $ $ S_{3}{n} = S_{1}^2(n) $ $ S_{4}{n} = S_{2} * \frac{3 * n ^ {2}+ 3 * n + 1 } {5} $ $$
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define int unsigned long long
using namespace std;
//int n = 1000000000000000;
int n;
int s1,s0,s2,s3,s4;
void HS() {
    int i = 0;
    while (i <= n) {
        s0 = s0 + 1;
        s1 = s1 + i;
        s2 = s2 + i * i;
        s3 = s3 + i * i * i;
        s4 = s4 + i * i * i * i;
        i = i + 1;
    }
    printf("%llu\n", s0);
    printf("%llu\n", s0);
    printf("%llu\n", s1);
    printf("%llu\n", s1);
    printf("%llu\n", s2);
    printf("%llu\n", s2);
    printf("%llu\n", s3);
    printf("%llu\n", s3);
    printf("%llu\n", s4);
    printf("%llu\n", s4);
}
main() {
    cin>>n;
//    HS();
    s0 = n+1;
    s1 = (n/2)*(n+1);
    s2 = (n/2)*((2*n+1)/3)*(n+1);
    s3 = s1*s1;
    s4 = (n/10)*((2*n+1)/3)*(n+1)*(3*n*n+3*n-1);
    cout<<s0<<endl;
    cout<<s0<<endl;
    cout<<s1<<endl;
    cout<<s1<<endl;
    cout<<s2<<endl;
    cout<<s2<<endl;
    cout<<s3<<endl;
    cout<<s3<<endl;
    cout<<s4<<endl;
    cout<<s4<<endl;
}

T5

问一个矩阵内多少个全1矩阵. 类同很多题目(如luogu仓鼠窝),裸上一个单调栈就好
#include <iostream>
#include<cstdio>
#define pr std::pair<int,int>
const int N = 5011;
int n, m;
bool data[N][N];

int seed;
int next_rand(){
    static const int P = 1000000007, Q = 83978833, R = 8523467;
    return seed = ((long long)Q * seed % P * seed + R) % P;
}

void generate_input(){
    std::cin >> n >> m;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            data[i][j] = bool((next_rand() % 8) > 0);
}
pr sta[N];int top;
int hi[N];
long long count3(){
    long long ans = 0;
    for(int i=1;i<=n;i++) {
        top = 0; int adc = 0;
        for(int j=1;j<=m;j++) {
            if(data[i][j]==0) {
                hi[j] = 0; adc = 0; top = 0;
                continue;
            }
            pr now = pr(++hi[j],1);
            while(top&&now.first<=sta[top].first) {
                adc -= sta[top].first*sta[top].second;
                now.second += sta[top].second;
                top--;
            }
            sta[++top] = now;
            adc += now.first * now.second;
            ans += adc;
        }
    }
    for(int i=1;i<=m;i++) hi[i] = 0;
    return ans;
}

int main(){
    freopen("program5.in","r",stdin);
    freopen("./OUT/5.out","w",stdout);
    std::cin >> seed;
    for(int i = 0; i < 10; i++){
        generate_input();
        std::cout << count3() << std::endl;
    }
    return 0;
}

T6

给你一个函数 $ F(X) = A*X^2 + B $,X初始值为0,T(狼狼范围)次自调用 $(X=F(X)) $之后X的值. 看上去很像Pollard-rho里的那个神奇随机函数? 利用判环算法找出循环节,就可以在跑5min之后找出答案啦真开心
#include <stdio.h>
#include<iostream>
unsigned long long a, b, c, t, k, n,tt;
void rd(unsigned long long &t) {
    t = (t * t * a + b) % c;
}

int main() {
    freopen("program6.in","r",stdin);
    freopen("./OUT/6.out","w",stdout);
    int i;
    for (i = 0; i <= 9; i++) {
        scanf("%llu %llu %llu %llu", &n, &a, &b, &c);
        t = 0; tt = 0;
        unsigned long long CIR = 1;
        for(;;CIR++) {
            rd(t);
            rd(tt); rd(tt);
            if(tt==t) break;
        }
        n-=CIR;
        n%=CIR;
        for(unsigned long long i=1;i<=n;i++) rd(t);
        printf("%llu\n", t);
    }
}

T7

16进制度(用字母代替)的数独.(也就是16宫格啦!) 直接爆搜,发现正着搜要挂,倒着爆搜枚举就可以了.
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
char s[20][20];
int er[21];
int h[22],l[22],o[22];
int ho(int x,int y) {
    return (x/4)*4+y/4;
}
bool flag;
void dfs(int x,int y) {
    if(x==-1) { flag = 1; return; }
    if(y==-1) {
        dfs(x-1,15); return;
    }
    if(s[x][y]!='?') {
        dfs(x,y-1); return;
    }
    for(int i=0;i<=15;i++) {
        if( ((h[x]&er[i])==0) && (0==(l[y]&er[i]) ) && (0==(o[ho(x,y)]&er[i]) ) ) {
            h[x] ^= er[i];
            l[y] ^= er[i];
            o[ho(x,y)] ^= er[i];
            s[x][y] = 'A' + i;
            dfs(x,y-1);
            if(flag) return;
            s[x][y] = '?';
            h[x] ^= er[i];
            l[y] ^= er[i];
            o[ho(x,y)] ^= er[i];
        }
    }
}
void solve(int points) {
    for (int i = 0; i <= 15; i++) {
        scanf("%s", s[i]);
        h[i] = l[i] = o[i] = 0;
    }
    for(int i=0;i<=15;i++) {
        for(int j=0;j<=15;j++) {
            if(s[i][j]!='?') {
                h[i]^=er[s[i][j]-'A'];
                l[j]^=er[s[i][j]-'A'];
                o[ho(i,j)]^=er[s[i][j]-'A'];
            }
        }
    }
    flag = 0;
    dfs(15,15);
    if (flag) {
        for (int k = 0; k <= points - 1; k++) {
            for (int i = 0; i <= 15; i++) {
                printf("%s", s[i]);
            }
            printf("\n");
        }
    }
    else{
        for(int k=0;k<=points-1;k++)
        printf("NO SOLUTION.\n");
    }
}

int main() {
    freopen("program7.in","r",stdin);
    freopen("./OUT/7.out","w",stdout);
    er[0] = 1;
    for(int i=1;i<=20;i++) er[i] = er[i-1]*2;
    solve(1);
    solve(2);
    solve(3);
    solve(4);
    return 0;
}

T8

给你一个八层循环的毒瘤代码.我们发现第一个答案显然是C(n,7),然后这是一个关于n的7次多项式.别的都和第一个的形式很像.大胆猜测这是一个关于n的7次多项式,发现模数是个质数,直接拉格朗日插值.
#include <stdio.h>
#include<iostream>
unsigned long long a, b, c, d, e, f, g, q, r, s, t, u, v, w, x, y, z;
unsigned long long p = 1234567891;

void HANSHU(unsigned long long n) {
    a = 0;
    q = 0;
    r = 0;
    s = 0;
    t = 0;
    u = 0;
    v = 0;
    w = 0;
    x = 0;
    y = 0;
    z = 0;
    a = 0;
    while (a < n) {
        a = a + 1;
        b = 0;
        while (b < n) {
            b = b + 1;
            c = 0;
            while (c < n) {
                c = c + 1;
                d = 0;
                while (d < n) {
                    d = d + 1;
                    e = 0;
                    while (e < n) {
                        e = e + 1;
                        f = 0;
                        while (f < n) {
                            f = f + 1;
                            g = 0;
                            while (g < n) {
                                g = g + 1;

                                if (a < b && b < c && c < d && d < e && e < f && f < g) {
                                    q = q + 1;
                                    q = q % p;
                                }

                                if (a < b && c < g && c < d && e < f && a < d) {
                                    r = r + 1;
                                    r = r % p;
                                }

                                if (a < d && d < f && c < f && c < e && b < d) {
                                    s = s + 1;
                                    s = s % p;
                                }

                                if (d < e && b < d && a < f && d < e && b < g) {
                                    t = t + 1;
                                    t = t % p;
                                }

                                if (c < f && b < f && b < c && f < g && b < f) {
                                    u = u + 1;
                                    u = u % p;
                                }

                                if (b < d && b < c && d < f && c < e && b < e) {
                                    v = v + 1;
                                    v = v % p;
                                }

                                if (a < c && a < b && c < e && b < f && e < g) {
                                    w = w + 1;
                                    w = w % p;
                                }

                                if (b < d && b < f && a < g && c < g && a < e) {
                                    x = x + 1;
                                    x = x % p;
                                }

                                if (b < f && a < c && c < d && a < c && b < e) {
                                    y = y + 1;
                                    y = y % p;
                                }

                                if (d < e && e < f && a < d && c < g && b < d) {
                                    z = z + 1;
                                    z = z % p;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
unsigned long long ksm(unsigned long long a,unsigned long long b) {
    unsigned long long ans = 1;
    for(;b;b>>=1,a=a*a%p)
        if(b&1) ans = ans*a%p;
    return ans;
}
unsigned long long Q[11],R[11],S[11],T[11],U[11],V[11],W[11],X[11],Y[11],Z[11];
unsigned long long laglang(unsigned long long *A,unsigned long long x) {
    x%=p;
    unsigned long long sm = 0;
    for(unsigned long long i=1;i<=9;i++) {
        unsigned long long s1 = 1; unsigned long long s2 = 1;
        for(unsigned long long j=1;j<=9;j++) {
            if(i==j) continue;
            s1 = s1*((x-j+p)%p)%p;
            s2 = s2*((i-j+p)%p)%p;
        }
        sm = (sm + A[i]*s1%p*ksm(s2,p-2)%p )%p;
    }
    return sm;
}
int main() {
    for(unsigned long long  i=1;i<=9;i++) {
        HANSHU(i);
        Q[i] = q; R[i] = r; S[i] = s; T[i] = t; U[i] = u; V[i] = v; W[i] = w;
        X[i] = x; Y[i] = y; Z[i] = z;
    }
    unsigned long long N;
    std::cin>>N;
    printf("%llu\n",laglang(Q,N));
    printf("%llu\n",laglang(R,N));
    printf("%llu\n",laglang(S,N));
    printf("%llu\n",laglang(T,N));
    printf("%llu\n",laglang(U,N));
    printf("%llu\n",laglang(V,N));
    printf("%llu\n",laglang(W,N));
    printf("%llu\n",laglang(X,N));
    printf("%llu\n",laglang(Y,N));
    printf("%llu\n",laglang(Z,N));

    return 0;
}

T9

这是一个毒瘤,给你MD5的转换代码,输入给了你md5码叫你转换成原码,我们发现在第二个测试点里面有一个英语词典 问题: 1.第一年NOI是哪年?4位数字。1984 2.在这一行,答案是最常见6位的密码。123456 3.在这一行你需要输出一个人名,他的照片在这个文件的开头。 一个字符画:陈立杰 orzorzorz 4.在这一行,答案是3个可见符号。 $_$ 真CCF 5.后面是一句名言(若干个单词),开始几个可以爆搜出来(以上问题也都可以爆搜出来)。如果历史学得好,你会发现这是《独立宣言》里的一句话woc woc woc woc ,最后一个爆搜不出来了,但是如果你做了T10,会发现里面有一份独立宣言orz orz orz orz,可以拿下来 综上,本题是出题人在嘿嘿嘿。

T10

题意自己看。 发现这道题开头有一个关于字母的循环调用,观察到规律,把开头那段关于字母的代码跑出以下代码之后替换掉就可以了。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

typedef unsigned long long ull;
ull o[30];
int main() {
    ull sm = 0; o[0] = 1;
    for(int i=1;i<=26;i++) {
        sm += o[i-1];
        o[i] = o[i-1]*(26-i)+sm;
        printf("void %c(){__=__+___*%lluull;}\n",(char)(i+'A'-1),o[i]);
    }
}
最后输出
void _(){__=__+___*1ull;}
void A(){__=__+___*26ull;}
void B(){__=__+___*651ull;}
void C(){__=__+___*15651ull;}
void D(){__=__+___*360651ull;}
void E(){__=__+___*7950651ull;}
void F(){__=__+___*167340651ull;}
void G(){__=__+___*3355140651ull;}
void H(){__=__+___*63923340651ull;}
void I(){__=__+___*1154150940651ull;}
void J(){__=__+___*19688020140651ull;}
void K(){__=__+___*316229927340651ull;}
void L(){__=__+___*4764358535340651ull;}
void M(){__=__+___*67038159047340651ull;}
void N(){__=__+___*876597565703340651ull;}
void O(){__=__+___*10591310445575340651ull;}
void P(){__=__+___*6772687681910030955ull;}
void Q(){__=__+___*5479948192676037227ull;}
void R(){__=__+___*12292036863279645291ull;}
void S(){__=__+___*11448514006979854955ull;}
void T(){__=__+___*5543854012881322603ull;}
void U(){__=__+___*7009382195709231723ull;}
void V(){__=__+___*14337023109848777323ull;}
void W(){__=__+___*6754098618987856491ull;}
void X(){__=__+___*2452069220114645611ull;}
void Y(){__=__+___*12294754496077775467ull;}
void Z(){__=__+___*3690695698331353707ull;}
小结:感觉今天花在这道毒瘤题上花费了太多时间了,考试遇到这种题还是要谨慎,不要一下子就沉迷进去那种,嘿嘿嘿,写完又得到十分的快感之中,很亏的,虽然时间越多分数,但却不是正比形式。以及遇到及时应变,总之实力如果有的话,除了像9问那种嘿嘿嘿题应该还是可以做的,还是要加强实力。
posted @ 2019-01-22 20:59  Newuser233  阅读(14)  评论(0)    收藏  举报