zoukankan      html  css  js  c++  java
  • [WC2015]未来程序(提交答案)

    sub1:ans=a*b%c,龟速乘即可。

    #include <stdio.h>
    #include <stdlib.h>
    unsigned long long a, b, c, d;
    unsigned long long mul(unsigned long long a,unsigned long long b)
    {
        unsigned long long x=0;
        while(b)
        {
            if(b&1)x=(x+a)%c;
            b>>=1,a=(a+a)%c;
        }
        return x;
    }
    void _() {
        scanf("%llu %llu %llu", &a, &b, &c);
        d = mul(a,b);
        printf("%llu
    ", d);
    }
    
    int main() {
        freopen("program1.in","r",stdin);
        freopen("program1.out","w",stdout);
        _();
        _();
        _();
        _();
        _();
        
        _();
        _();
        _();
        _();
        _();
    }
    生成代码

    sub2:发现是一个递推式,每次转移如下:a'=a+2b+c,b'=a+b,c'=a,直接构造3*3的矩阵,进行矩乘即可。

    #include<cstdio>
    #include<cstring>
    using namespace std;
    long long n,p;
    struct mat{
        int a[3][3];
        mat(){memset(a,0,sizeof a);}
        void init(){memset(a,0,sizeof a);for(int i=0;i<3;i++)a[i][i]=1;}
        void prepare()
        {
            memset(a,0,sizeof a);
            a[0][0]=a[0][1]=a[0][2]=a[1][1]=a[2][0]=1,a[1][0]=2;
        }
    };
    mat operator*(mat a,mat b)
    {
        mat c;
        for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
        for(int k=0;k<3;k++)
        c.a[i][j]=(c.a[i][j]+1ll*a.a[i][k]*b.a[k][j])%p;
        return c;
    }
    void _______() {
        scanf("%lld %lld", &n, &p);
        mat A,ret;
        A.prepare(),ret.init();
        while(n)
        {
            if(n&1)ret=ret*A;
            A=A*A,n>>=1;
        }
        long long a=ret.a[0][0],b=ret.a[0][1],c=ret.a[0][2],d=((a-2*b+c)%p+p)%p;
        printf("%lld
    ", d);
    }
    int main() {
        freopen("program2.in","r",stdin);
        freopen("program2.out","w",stdout);
        _______();
        _______();
        _______();
        _______();
        _______();
        _______();
        _______();
        _______();
        _______();
        _______();
        return 0;
    }
    生成代码

    sub3:求Σik,其中k∈[0,4],手算求答案即可,这个没写代码,计算器算算即可。

    1000000000000001
    1000000000000001
    2538972135152631808
    2538972135152631808
    2806098670314569728
    2806098670314569728
    6570342264898322432
    6570342264898322432
    10067259324320137216
    10067259324320137216
    答案

    sub4:随机生成n*n(n<=5000)的0/1矩阵,第一问求值为1的格子选2个进行排列的方案数,显然就是x*(x-1)(x为值为1的格子数);第二问是求对于每个值为1的格子,距离它最近的值为0的格子的距离,输出距离和,显然可以bfs多元最短路搜索,复杂度可以O(Tn2),大约5~10s能跑出答案

    #include <iostream>
    using namespace std;
    const int N = 5000, inf = 0x3F3F3F3F;
    int n, m, type,dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
    bool mp[N + 11][N + 11],vis[N+11][N+11];
    int qx[N*N+11],qy[N*N+11],d[N+11][N+11];
    long long ans;
    int seed;
    int next_rand(){
        static const int P = 1000000007, Q = 83978833, R = 8523467;
        return seed = ((long long)Q * seed % P * seed + R) % P;
    }
    long long count1()
    {
        ans = 0LL;
        for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++)
        if(mp[i][j])ans++;
        return ans*(ans-1);
    }
    long long count2()
    {
        ans = 0LL;
        int qs=0,qe=0;
        for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        if(mp[i][j])vis[i][j]=0;
        else vis[i][j]=1,d[i][j]=0,qx[qe]=i,qy[qe++]=j;
        while(qs<qe)
        {
            int x=qx[qs],y=qy[qs++];
            for(int i=0;i<4;i++)
            {
                int u=x+dx[i],v=y+dy[i];
                if(u<0||u>=n||v<0||v>=m||vis[u][v])continue;
                vis[u][v]=1,d[u][v]=d[x][y]+1,qx[qe]=u,qy[qe++]=v;
                ans+=d[u][v];
            }
        }
        return ans;
    }
    int main(){
        freopen("program4.in","r",stdin);
        freopen("program4.out","w",stdout);
        cin >> seed;
        for(int i = 0; i < 10; i++){
            cin >> n >> m >> type;
            for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++)
            mp[i][j] = bool((next_rand() % 8) > 0);
            cout << (type == 1 ? count2() : count1()) <<endl;
        }
        return 0;
    }
    生成代码

    sub5:随机生成n*n(n<=5000)的0/1矩阵,求全1矩阵个数。这题的简化版:https://www.cnblogs.com/hfctf0210/p/10852851.html

    #include <iostream>
    
    const int N = 5011;
    int n, m,c[N][N],st[N];
    bool data[N][N];
    long long sum[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);
    }
    long long count3(){
        long long ret=0;
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        c[i][j]=data[i][j]?c[i-1][j]+1:0;
        int top;
        for(int i=1;i<=n;i++)
        {
            st[0]=top=0;
            for(int j=1;j<=n;j++)
            if(!c[i][j])st[0]=j,top=0;
            else{
                while(top&&c[i][j]<=c[i][st[top]])top--;
                st[++top]=j,sum[top]=sum[top-1]+1ll*(j-st[top-1])*c[i][j];
                ret+=sum[top];
            }
        }
        return ret;
    }
    
    int main(){
        freopen("program5.in","r",stdin);
        freopen("program5.out","w",stdout);
        std::cin >> seed;
        for(int i = 0; i < 10; i++){
            generate_input();
            std::cout << count3() << std::endl;
        }
    
        return 0;
    }
    生成代码

    sub6:发现式子还有自然溢出,快速幂/矩阵类显然不行,想到floyd套圈,学习笔记链接:https://www.cnblogs.com/hfctf0210/p/10725670.html,不过要跑300~400s

    #include<iostream>
    using namespace std;
    typedef unsigned long long ull;
    ull T,n,a,b,c;
    ull s,t,tim,tn,tm;
    int main()
    {
        freopen("program6.in","r",stdin);
        freopen("program6.out","w",stdout);
        int T=10;
        while(T--)
        {
            cin>>n>>a>>b>>c;
            s=t=tn=0,tm=2;
            while(1)
            {
                t=(a*t*t+b)%c;
                tn++;
                if(s==t)break;
                if(tn==tm)tn=0,tm<<=1,s=t;
            }
            s=t=tim=0;
            while(tim<tn)t=(a*t*t+b)%c,tim++;
            tim=1;
            while(s!=t)s=(a*s*s+b)%c,t=(a*t*t+b)%c,tim++;
            tm=(n-tim)%tn+1;
            tim=1;
            while(tim<=tm)s=(a*s*s+b)%c,tim++;
            cout<<s<<endl;
        }
    }
    生成代码

    sub8:把a~g当成7个点,化成图形,发现10张图需要枚举的变量均不超过2个,由于n%mod很小(大约1e6级别),对于需要枚举不超过1个的8张图,直接枚举即可,剩下2张图直接手推/枚举打表即可。

    1018333390
    993704934
    1053807588
    1144151985
    712062141
    530076748
    520686243
    337499021
    820275783
    80253986
    答案

    sub7/9/10:咕了,太菜了不会

  • 相关阅读:
    基本Dos命令
    安装java开发环境
    windouws常用快捷键
    elasticsearch(ES)
    使用kibana操作elasticsearch(es)
    Dubbo的负载均衡
    springboot结合Dubbo的使用
    Dubbo
    zookeeper-理解
    springboot结合FTP服务器实现文件上传
  • 原文地址:https://www.cnblogs.com/hfctf0210/p/10907965.html
Copyright © 2011-2022 走看看