• 小米 OJ 编程比赛 03 月常规赛


    A.数学等式

    数据比较小,可以暴力+折半枚举。

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=200010;
    map<int,int>mp;
    int main()
    {
        int N,A,B,C,D,E; ll ans=0;
        scanf("%d%d%d%d%d",&A,&B,&C,&D,&E);
        rep(i,-50,50)
         rep(j,-50,50)
          rep(k,-50,50){
            if(i*j*k==0) continue;
            int x=A*i*i*i+B*j*j*j+C*k*k*k;
            mp[x]++;
        }
        rep(i,-50,50)
         rep(j,-50,50){
           if(i*j==0) continue;
           int x=D*i*i*i+E*j*j*j;
           ans+=mp[x];
        }
        printf("%lld
    ",ans);
        return 0;
    }
    View Code

    B.贪吃的细胞

    最小生成树,即是S和所有的营养液连通,我们把S和营养液看成关键点,那么预处理出关键点之间的两两距离(BFS即可)。

    然后从S开始,跑基于prim的最小生成树。 题中,我们需要加限制,即如果A->B要连边(A处一个细胞到B处),那么A的细胞数不能为0,而一个细胞跑到B后,变为c[B]+1个,同时用B到其他点的距离更新最小距离。

    (由于std出了问题,我们先假设代码是对的。

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=210;
    const int inf=1000000;
    char c[maxn][maxn];
    int id[maxn][maxn],vis[maxn][maxn],X[maxn],Y[maxn],Z[maxn];
    int T,N,M,tot,Sx,Sy,num;
    int peo[maxn],used[maxn],Dis[maxn][maxn],ans;
    int xx[4]={1,-1,0,0},yy[4]={0,0,1,-1};
    int dis[maxn][maxn][maxn],qx[maxn*maxn],qy[maxn*maxn],head,tail;
    struct in{
        int id,dis,from;
        in(){}
        in(int ii,int dd,int ff):id(ii),dis(dd),from(ff){}
        friend bool operator <(in w,in v){
            return w.dis>v.dis;
        }
    };
    priority_queue<in>q;
    void dfs1(int x,int y)
    {
        if(x<1||x>N||y<1||y>M||vis[x][y]||c[x][y]=='#') return ;
        vis[x][y]=1; if(c[x][y]>='1'&&c[x][y]<='9') num++;
        rep(i,0,3) dfs1(x+xx[i],y+yy[i]);
    }
    void get(int p) //得到关键点和其他关键点的距离
    {
        rep(i,1,N) rep(j,1,M) dis[p][i][j]=inf;
        rep(i,1,tot) Dis[p][i]=inf;
        head=tail=0; head++;
        qx[head]=X[p],qy[head]=Y[p]; dis[p][X[p]][Y[p]]=0;
        while(tail<head){
            tail++;
            int tx=qx[tail],ty=qy[tail];
            rep(i,0,3){
                int rx=tx+xx[i],ry=ty+yy[i];
                if(rx>=1&&rx<=N&&ry>=1&&ry<=M&&c[rx][ry]!='#'&&dis[p][rx][ry]==inf){
                    dis[p][rx][ry]=dis[p][tx][ty]+1;
                    if(id[rx][ry]) Dis[p][id[rx][ry]]=dis[p][rx][ry];
                    head++; qx[head]=rx; qy[head]=ry;
                }
            }
        }
    }
    void solve()
    {
        rep(i,0,tot) get(i);
        rep(i,1,tot) peo[i]=used[i]=0;
        peo[0]=1; ans=0; int sz=0; used[0]=1;
        rep(i,1,tot) if(Dis[0][i]!=inf){
            q.push(in(i,Dis[0][i],0));  //sz++;
        }
        while(!q.empty()){  //每次贪心的找最小边
            in t=q.top(); q.pop();
            if(t.id&&peo[t.from]&&!used[t.id]){
                peo[t.from]--; used[t.id]=1; ans+=t.dis;
                peo[t.id]+=1+Z[t.id]; sz++;
                rep(i,1,tot) if(!used[i]&&Dis[t.id][i]!=inf){ //来源有多的细胞,且目的地没有被用掉,则合法
                   q.push(in(i,Dis[t.id][i],t.id));
                }
            }
        }
    }
    int main()
    {
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&N,&M);
            rep(i,1,N) scanf("%s",c[i]+1);
            tot=num=0;
            rep(i,1,N) rep(j,1,M) id[i][j]=vis[i][j]=0;
            rep(i,1,N)
             rep(j,1,M){
                 if(c[i][j]>='1'&&c[i][j]<='9') {
                    id[i][j]=++tot;
                    X[tot]=i; Y[tot]=j; Z[tot]=c[i][j]-'0';
                 }
                 else if(c[i][j]=='S'||c[i][j]=='s') X[0]=Sx=i,Y[0]=Sy=j;
            }
            dfs1(Sx,Sy);
            if(num!=tot){ puts("-1"); continue;}
            solve();
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=210;
    const int inf=1000000;
    char c[maxn][maxn];
    int id[maxn][maxn],vis[maxn][maxn],X[maxn],Y[maxn],Z[maxn];
    int T,N,M,tot,Sx,Sy,num;
    int peo[maxn],used[maxn],Dis[maxn][maxn],ans;
    int xx[4]={1,-1,0,0},yy[4]={0,0,1,-1};
    int dis[maxn][maxn][maxn],qx[maxn*maxn],qy[maxn*maxn],head,tail;
    struct in{
        int id,dis,from;
        in(){}
        in(int ii,int dd,int ff):id(ii),dis(dd),from(ff){}
        friend bool operator <(in w,in v){
            return w.dis>v.dis;
        }
    };
    priority_queue<in>q;
    void dfs1(int x,int y)
    {
        if(x<1||x>N||y<1||y>M||vis[x][y]||c[x][y]=='#') return ;
        vis[x][y]=1; if(c[x][y]>='1'&&c[x][y]<='9') num++;
        rep(i,0,3) dfs1(x+xx[i],y+yy[i]);
    }
    void get(int p)
    {
        rep(i,1,N) rep(j,1,M) dis[p][i][j]=inf;
        rep(i,1,tot) Dis[p][i]=inf;
        head=tail=0; head++;
        qx[head]=X[p],qy[head]=Y[p]; dis[p][X[p]][Y[p]]=0;
        while(tail<head){
            tail++;
            int tx=qx[tail],ty=qy[tail];
            rep(i,0,3){
                int rx=tx+xx[i],ry=ty+yy[i];
                if(rx>=1&&rx<=N&&ry>=1&&ry<=M&&c[rx][ry]!='#'&&dis[p][rx][ry]==inf){
                    dis[p][rx][ry]=dis[p][tx][ty]+1;
                    if(id[rx][ry]) Dis[p][id[rx][ry]]=dis[p][rx][ry];
                    head++; qx[head]=rx; qy[head]=ry;
                }
            }
        }
    }
    void solve()
    {
        rep(i,0,tot) get(i);
        rep(i,1,tot) peo[i]=used[i]=0;
        peo[0]=1; ans=0; int sz=0; used[0]=1;
        rep(i,1,tot) if(Dis[0][i]!=inf){
            q.push(in(i,Dis[0][i],0));  //sz++;
        }
        while(!q.empty()){
            in t=q.top(); q.pop();
            if(t.id&&peo[t.from]&&!used[t.id]){
                peo[t.from]--; used[t.id]=1; ans+=t.dis;
                peo[t.id]+=1+Z[t.id]; sz++;
                rep(i,1,tot) if(!used[i]&&Dis[t.id][i]!=inf){
                   q.push(in(i,Dis[t.id][i],t.id));
                }
            }
        }
    }
    int main()
    {
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&N,&M);
            rep(i,1,N) scanf("%s",c[i]+1);
            tot=num=0;
            rep(i,1,N) rep(j,1,M) id[i][j]=vis[i][j]=0;
            rep(i,1,N)
             rep(j,1,M){
                 if(c[i][j]>='1'&&c[i][j]<='9') {
                    id[i][j]=++tot;
                    X[tot]=i; Y[tot]=j; Z[tot]=c[i][j]-'0';
                 }
                 else if(c[i][j]=='S'||c[i][j]=='s') X[0]=Sx=i,Y[0]=Sy=j;
            }
            dfs1(Sx,Sy);
            if(num!=tot){ puts("-1"); continue;}
            solve();
            printf("%d
    ",ans);
        }
        return 0

    C.小爱密码 2.0

    一看就是规律题,打出前面几个,发现除了前面两个其他的下标都是素数,那么我们素数筛得到所有对应的fib下标即可。 然后针对问题,我们矩阵乘法得到对应的答案,然后exgcd求逆元。(m不是素数,不能快速幂求逆元。

    打表代码:

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=7500010;
    ll a[40];
    int main()
    {
        a[3]=2; a[4]=3;
        rep(i,5,30) a[i]=a[i-1]+a[i-2];
        rep(i,3,30){
            int f=0;
            rep(j,3,i-1) if(a[i]%a[j]==0) f=1;
            if(!f) cout<<i<<" ";
        }
        return 0;
    }
    View Code

    矩阵快速幂代码:

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=7500010;
    bool vis[maxn]; int p[500010],cnt,Mod;
    void prime()
    {
        for(int i=2;i<maxn;i++){
            if(!vis[i]){
                p[++cnt]=i;
                if(cnt==500000) break;
            }
            for(int j=1;j<=cnt&&i*p[j]<maxn;j++){
                vis[i*p[j]]=1;
                if(i%p[j]==0) break;
            }
        }
    }
    struct mat{
        int m[2][2];
        mat(){memset(m,0,sizeof(m));}
        friend mat operator *(mat a,mat b){
            mat res;
            rep(i,0,1)
             rep(j,0,1)
              rep(k,0,1) (res.m[i][j]+=1LL*a.m[i][k]*b.m[k][j]%Mod)%=Mod;
            return res;
        }
        friend mat operator ^(mat a,int x){
            mat res; res.m[0][0]=res.m[1][1]=1;
            while(x){
                if(x&1) res=res*a; a=a*a; x>>=1;
            } return res;
        }
    };
    int getfib(int N)
    {
        mat ans,base;
        ans.m[0][0]=ans.m[1][0]=1;
        base.m[0][0]=base.m[0][1]=base.m[1][0]=1;
        ans=(base^(N-2))*ans;
        return ans.m[0][0];
    }
    void exgcd(int a,int b,int d,int &x,int &y)
    {
        if(b==0){ d=a; x=1; y=0; return;}
        exgcd(b,a%b,d,y,x); y-=a/b*x;
    }
    int rev(int a,int b)
    {
        int x,y,d;
        exgcd(a,b,d,x,y); return (x+b)%b;
    }
    int main()
    {
        prime(); int N;
        p[1]=3; p[2]=4;
        while(~scanf("%d%d",&N,&Mod)){
            N=p[N];
            int ans=getfib(N);
            ans=1LL*ans*rev(3,Mod)%Mod;
            int L=0,x=ans;
            while(x){ x/=10; L++;}
            if(ans==0) L++;
            rep(i,1,9-L) putchar('*');
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    自增长主键Id的另类设计
    Android 混淆那些事儿
    H5 和移动端 WebView 缓存机制解析与实战
    快速上手 Kotlin 的 11 招
    教你 Debug 的正确姿势——记一次 CoreMotion 的 Crash
    小程序组件化框架 WePY 在性能调优上做出的探究
    基于 TensorFlow 在手机端实现文档检测
    HTTPS 原理浅析及其在 Android 中的使用
    Bugly 多渠道热更新解决方案
    Swift 对象内存模型探究(一)
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10625322.html
Copyright © 2020-2023  润新知