zoukankan      html  css  js  c++  java
  • 9.29noip模拟试题

     

    环上的游戏(cycle)

    有一个取数的游戏。初始时,给出一个环,环上的每条边上都有一个非负整数。这些整数中至少有一个0。然后,将一枚硬币放在环上的一个节点上。两个玩家就是以这个放硬币的节点为起点开始这个游戏,两人轮流取数,取数的规则如下:

    (1)选择硬币左边或者右边的一条边,并且边上的数非0;

    (2)将这条边上的数减至任意一个非负整数(至少要有所减小);

    (3)将硬币移至边的另一端。

    如果轮到一个玩家走,这时硬币左右两边的边上的数值都是0,那么这个玩家就输了。

    如下图,描述的是Alice和Bob两人的对弈过程,其中黑色节点表示硬币所在节点。结果图(d)中,轮到Bob走时,硬币两边的边上都是0,所以Alcie获胜。

    现在,你的任务就是根据给出的环、边上的数值以及起点(硬币所在位置),判断先走方是否有必胜的策略。

    【输入格式】

    第一行一个整数N(N≤20),表示环上的节点数。

    第二行N个数,数值不超过30,依次表示N条边上的数值。硬币的起始位置在第一条边与最后一条边之间的节点上。

    【输出格式】

    仅一行。若存在必胜策略,则输出“YES”,否则输出“NO”。

    【样例】

    cycle.in cycle.out

    4

    2 5 3 0 YES

    cycle.in cycle.out

    3

    0 0 0 NO

    最后取到数的人获胜

     博弈

    /*
    比较简单的博弈题
    手动模拟一下 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n,a[50],s;
    int main()
    {
        freopen("cycle.in","r",stdin);
        freopen("cycle.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
            if(a[i]==0)break;
            else s++;
        for(int i=n;i>=1;i--)
            if(a[i]==0)break;
            else s++;
        if(s&1)printf("YES
    ");
        else printf("NO
    ");
        return 0;
    }
    View Code

    舞蹈课(dancingLessons)

    问题描述

    有n个人参加一个舞蹈课。每个人的舞蹈技术由整数来决定。在舞蹈课的开始,他们从左到右站成一排。当这一排中至少有一对相邻的异性时,舞蹈技术相差最小的那一对会出列并开始跳舞。如果相差最小的不止一对,那么最左边的那一对出列。一对异性出列之后,队伍中的空白按原顺序补上(即:若队伍为ABCD,那么BC出列之后队伍变为AD)。舞蹈技术相差最小即是的绝对值最小。

    你的任务是,模拟以上过程,确定跳舞的配对及顺序。

    输入

    第一行为正整数:队伍中的人数。下一行包含n个字符B或者G,B代表男,G代表女。下一行为n个整数。所有信息按照从左到右的顺序给出。在50%的数据中,。

    输出

    第一行:出列的总对数k。接下来输出k行,每行是两个整数。按跳舞顺序输出,两个整数代表这一对舞伴的编号(按输入顺序从左往右1至n编号)。请先输出较小的整数,再输出较大的整数。

    样例输入

    4

    BGBG

    4 2 4 3

    样例输出

    2

    3 4

    1 2

    样例输入

    4

    BGBB

    1 1 2 3

    样例输出

    1

    1 2

     贪心

    /*
    贪心+堆优化
    一开始把所有挨着的男女放进去
    然后拿出Abs最小的 同时看看新生成的挨着的能不能组合成一组
    注意一些细节的处理
    开始wa了一个点 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<vector>
    #define maxn 200010
    #define inf 0x7fffffff
    using namespace std;
    int n,a[maxn],cnt,f[maxn],s1,s2;
    char c[maxn];
    struct node{
        int l,r,C;
        bool operator < (const node &x) const{
            if(x.C==C)return x.l<l;
            return x.C<C;
        }
    }ans[maxn],t;
    priority_queue<node>q;
    int init(){
        int x=0,f=1;char s=getchar();
        while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
        while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
        return x*f;
    }
    int Abs(int x){
        return x<0?-x:x;
    }
    int main()
    {
    //    freopen("dancingLessons.in","r",stdin);
        //freopen("dancingLessons.out","w",stdout);
        n=init();
        scanf("%s",c+1);
        for(int i=1;i<=n;i++)
            if(c[i]=='B')s1++;
            else s2++;
        for(int i=1;i<=n;i++)
            a[i]=init();
        for(int i=2;i<=n;i++)
            if(c[i-1]!=c[i])
                q.push((node){i-1,i,Abs(a[i]-a[i-1])});
        while(!q.empty()){
            int falg=0;
            while(1){
                if(q.empty()){falg=1;break;}
                t=q.top();q.pop();
                if(f[t.l]||f[t.r])continue;
                else break;
            }
            if(q.empty()&&falg)break;//这里多一个falg标记 表示q空时最后一个合不合法 
            ans[++cnt].l=t.l;ans[cnt].r=t.r;
            f[t.l]=1;f[t.r]=1;
            int L=t.l-1,R=t.r+1;
            while(f[L])L--;
            while(f[R])R++;
            if(L&&R<=n&&c[L]!=c[R])
                q.push((node){L,R,Abs(a[R]-a[L])});
        }
        printf("%d
    ",cnt);
        for(int i=1;i<=cnt;i++)
            printf("%d %d
    ",ans[i].l,ans[i].r);
        return 0;
    }
    View Code

    数位和乘积(digit.cpp/c/pas)

    【题目描述】

    一个数字的数位和乘积为其各位数字的乘积。求所有的N位数中有多少个数的数位和乘积恰好为K。请注意,这里的N位数是可以有前导零的。比如01,02视为二位数,但是他们的数位和乘积都是0。

    【输入格式】

    一行两个整数N,K

    【输出格式】

    一个行一个整数表示结果。

    【样例输入】

    2 3

    【样例输出】

    2

    【样例输入2】

    2 0

    【样例输出2】

    19

     

    【数据范围】

    对于20%:N <= 6。

    对于50%:N<=16

    存在另外30%:K=0。

    对于100%:N  <= 50,0 <= K <= 10^9。

     暴力50

    /*
    我是蒟蒻没有想出正解...
    打了个暴力 当然也不是裸裸的
    k==0 10^n-9^n 
    分成两段 每段分别暴力 在hash一下(不知为啥hash最小的数据不对 写了map)
    还有一些小剪枝
    目测n<=15的都能过
    但是说好的%30<=16结果全尼玛是16 你故意的吧
    然后就只拿到了基础的暴力分50 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<map>
    #include<ctime>
    #define mod 233333
    using namespace std;
    int n,k,N,falg,ans[100],J[100];
    map<int,int>p;
    void Add(int a[100],int b[100]){
        int c[30];
        memset(c,0,sizeof(c));
        int len=max(a[0],b[0]);
        for(int i=1;i<=len;i++)
            c[i]=a[i]+b[i];
        for(int i=1;i<=len;i++)
            if(c[i]>9){
                c[i+1]++;c[i]%=10;
            }
        if(c[len+1])len++;c[0]=len;
        for(int i=0;i<=len;i++)a[i]=c[i];
    }
    void Jian(int a[100],int b[100]){
        int c[100];
        memset(c,0,sizeof(c));
        int len=max(a[0],b[0]);
        for(int i=1;i<=len;i++)
            c[i]=a[i]-b[i];
        for(int i=1;i<=len;i++)
            if(c[i]<0){
                c[i+1]--;c[i]+=10;
            }
        for(int i=len;i>=0;i--)
            if(c[i]){
                c[0]=i;break;
            }
        for(int i=0;i<=len;i++)a[i]=c[i];
    }
    void Mul(int a[100],int x){
        int c[100];
        memset(c,0,sizeof(c));
        int len=a[0];
        for(int i=1;i<=len;i++)
            c[i]=a[i]*x;
        for(int i=1;i<=len;i++)
            if(c[i]>9){
                c[i+1]+=c[i]/10;
                c[i]%=10;
            }
        while(c[len+1]>9){
            len++;
            c[len+1]+=c[len]/10;
            c[len]%=10;
        }
        if(c[len+1])len++;c[0]=len;
        for(int i=0;i<=len;i++)a[i]=c[i];
    }
    void Cal(int x){
        int a[100];
        memset(a,0,sizeof(a));
        while(x){
            a[++a[0]]=x%10;x/=10;
        }
        Add(ans,a);
    }
    void Dfs(int now,int s,int r){
        if(r>k)return;
        if(now==N+1){
            if(!falg)p[r]++;
            else{
                if(r){
                    int t=k/r;
                    if(t*r==k)Cal(p[t]);
                }
            }
            return;
        }
        for(int i=1;i<=9;i++)
            Dfs(now+1,s*10+i,r*i);
    }
    void Solve(){
        ans[0]=1;ans[1]=1;
        J[0]=1;J[1]=1;
        for(int i=1;i<=n;i++)
            Mul(ans,10);
        for(int i=1;i<=n;i++)
            Mul(J,9);
        Jian(ans,J);
    }
    int main()
    {
        //freopen("digit.in","r",stdin);
        //freopen("digit.out","w",stdout);
        scanf("%d%d",&n,&k);
        if(k==0)Solve();
        else{
            N=n/2;Dfs(1,0,1);
            falg=1;
            N=n;Dfs(n/2+1,0,1);
        }
        for(int i=max(ans[0],1);i>=1;i--)
            printf("%d",ans[i]);
        return 0;
    }
    View Code

    正解dp

    /*
    正解还是很机智的Orz
    f[i][j][k][l][r]前i位选了j个2 k个3 l个5 r个7的方案数
    然后+个高精就ok了 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n,k,ans[100],J[100];
    int f[32][32][32][32][40];
    void Add(int a[100],int b[100]){
        int c[30];
        memset(c,0,sizeof(c));
        int len=max(a[0],b[0]);
        for(int i=1;i<=len;i++)
            c[i]=a[i]+b[i];
        for(int i=1;i<=len;i++)
            if(c[i]>9){
                c[i+1]++;c[i]%=10;
            }
        if(c[len+1])len++;c[0]=len;
        for(int i=0;i<=len;i++)a[i]=c[i];
    }
    void Jian(int a[100],int b[100]){
        int c[100];
        memset(c,0,sizeof(c));
        int len=max(a[0],b[0]);
        for(int i=1;i<=len;i++)
            c[i]=a[i]-b[i];
        for(int i=1;i<=len;i++)
            if(c[i]<0){
                c[i+1]--;c[i]+=10;
            }
        for(int i=len;i>=0;i--)
            if(c[i]){
                c[0]=i;break;
            }
        for(int i=0;i<=len;i++)a[i]=c[i];
    }
    void Mul(int a[100],int x){
        int c[100];
        memset(c,0,sizeof(c));
        int len=a[0];
        for(int i=1;i<=len;i++)
            c[i]=a[i]*x;
        for(int i=1;i<=len;i++)
            if(c[i]>9){
                c[i+1]+=c[i]/10;
                c[i]%=10;
            }
        while(c[len+1]>9){
            len++;
            c[len+1]+=c[len]/10;
            c[len]%=10;
        }
        if(c[len+1])len++;c[0]=len;
        for(int i=0;i<=len;i++)a[i]=c[i];
    }
    void Cal(int x){
        int a[100];
        memset(a,0,sizeof(a));
        while(x){
            a[++a[0]]=x%10;x/=10;
        }
        Add(ans,a);
    }
    void Solve(){
        ans[0]=1;ans[1]=1;
        J[0]=1;J[1]=1;
        for(int i=1;i<=n;i++)
            Mul(ans,10);
        for(int i=1;i<=n;i++)
            Mul(J,9);
        Jian(ans,J);
        for(int i=max(ans[0],1);i>=1;i--)
            printf("%d",ans[i]);
    }
    void solve(){
        int t1=0,t2=0,t3=0,t4=0;
        while(k%2==0)k/=2,t1++;
        while(k%3==0)k/=3,t2++;
        while(k%5==0)k/=5,t3++;
        while(k%7==0)k/=7,t4++;
        if(k>1){cout<<0;return;}
        f[0][0][0][0][0]=1;
        f[0][0][0][0][1]=1;
        for(int i=1;i<=n;i++)
            for(int j=t1;j>=0;j--)
                for(int k=t2;k>=0;k--)
                    for(int l=t3;l>=0;l--)
                        for(int r=t4;r>=0;r--){
                            if(j>=1)Add(f[j][k][l][r],f[j-1][k][l][r]);//2
                            if(k>=1)Add(f[j][k][l][r],f[j][k-1][l][r]);//3
                            if(j>=2)Add(f[j][k][l][r],f[j-2][k][l][r]);//4
                            if(l>=1)Add(f[j][k][l][r],f[j][k][l-1][r]);//5
                            if(j>=1&&k>=1)Add(f[j][k][l][r],f[j-1][k-1][l][r]);//6
                            if(r>=1)Add(f[j][k][l][r],f[j][k][l][r-1]);//7
                            if(j>=3)Add(f[j][k][l][r],f[j-3][k][l][r]);//8
                            if(k>=2)Add(f[j][k][l][r],f[j][k-2][l][r]);//9
                        }
        for(int i=max(f[t1][t2][t3][t4][0],1);i>=1;i--)
            printf("%d",f[t1][t2][t3][t4][i]);
    }
    int main()
    {
        //freopen("digit.in","r",stdin);
        //freopen("digit.out","w",stdout);
        scanf("%d%d",&n,&k);
        if(k==0)Solve();
        else solve();
        return 0;
    }
    View Code
  • 相关阅读:
    SaltStack api使用
    saltstack批量管理文件和计划任务
    Kubernetes应用管理器OpenKruise之CloneSet
    Kubernetes日志系统新贵Loki-Stack
    Prometheus Operator自定义监控项
    MySQL错误修复:Table xx is marked as crashed and last (automatic?) repair failed
    kubernetes存储类与PV与PVC关系及实践
    手把手教你使用rpm部署ceph集群
    什么是dockerfile?
    RabbitMQ
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5920076.html
Copyright © 2011-2022 走看看