zoukankan      html  css  js  c++  java
  • 10月17日考试 题解(位运算+状压DP+打表+大模拟)

    T1 神奇的位运算

    题目大意:给定$n$个长度为$m$的$01$串,每一位都有一种位运算,为与(&),或(|),异或(^)的一种。现为了确定每一位的位运算的种类,问最少添加多少字符串。

    可以发现每一位都必须至少有两个$1$和一个$0$。判断一下即可。

    代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int N=505;
    char s[N];
    int T,n,m,num[N][2];
    int main(){
        scanf("%d",&T);
        while(T--)
        {
            memset(num,0,sizeof(num));
            scanf("%d%d",&n,&m);
            for (int i=1;i<=n;i++)
            {
                scanf("%s",s+1);
                for (int j=1;j<=m;j++)
                    num[j][s[j]-'0']++;
            }
            int k=0;
            for (int i=1;i<=m;i++)
            {
                int flag=0;
                if (num[i][0]<1) flag++;
                if (num[i][1]<2) flag+=2-num[i][1];
                k=max(flag,k);
            }
            printf("%d
    ",k);
        }
        return 0;
    }

    T2 终焉之数列

    题目大意:给定一个长度为$n$的数列$a_i$,现要求确定一个长度相等的序列$b_i$,使得$b$中任意两个数互质且最小化$sumlimits_{i=1}^n |a_i-b_i|$。$nleq 100,a_ileq 30$。

    发现$1-58$内只有$16$个质数,可以考虑状压(选$59$和选$1$是等价的)。

    设$f_{i,s}$表示前$i$个数质因数状态为$s$的方案数。有转移:

    $f_{i+1,s'}=f_{i,s}+|num-a_i|$

    其中,$s'$为后继状态,$num$为一个合法的数。对于每个$s$合法的$num$可以预处理得到,对于$s$和$num$的$s'$也可以预处理得到。题目要求输出方案,记录一下前驱即可。时间复杂度$O(2^{16} imes 58 imes n)$。

    代码:

    #include<cstdio>
    #include<iostream>
    #include<stack>
    #include<vector>
    #include<cstring>
    #include<cmath>
    using namespace std;
    const int N=105;
    const int M=65536;
    int prime[20]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
    int f[N][M+5],g[N][M+5],t[N][M+5],s[N][M+5],a[N],n;
    vector<int> v[M+5];
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
        return x*f; 
    }
    int main()
    {
        n=read();
        for (int i=1;i<=n;i++) a[i]=read();
        for(int i=0;i<(1<<16);i++){
            for(int j=1;j<=58;j++){
                int flag=0;
                for(int k=1;k<=16;k++){
                    if((j%prime[k]==0)&&(i&(1<<(k-1)))){
                        flag=1;
                        break;
                    }
                }
                if(flag==0){
                    v[i].push_back(j);
                    int ss=i;
                    for(int k=1;k<=16;k++){
                        if((j%prime[k]==0)&&((i&(1<<(k-1)))==0)){
                            ss|=(1<<(k-1));
                        }
                    }
                    s[j][i]=ss;
                }
            }
        }
        memset(f,0x3f,sizeof(f));
        f[0][0]=0;
        for(int i=0;i<(1<<16);i++){
            for(int j=0;j<n;j++){
                for(int k=0;k<v[i].size();k++){
                    if(f[j+1][s[v[i][k]][i]]>f[j][i]+abs(v[i][k]-a[j+1])){
                        f[j+1][s[v[i][k]][i]]=f[j][i]+abs(v[i][k]-a[j+1]);
                        g[j+1][s[v[i][k]][i]]=v[i][k];
                        t[j+1][s[v[i][k]][i]]=i;
                    }
                }
            }
        }
        int pos,minn=0x3f3f3f3f;
        for(int i=0;i<(1<<16);i++){
            if(f[n][i]<minn){
                pos=i;
                minn=f[n][i];
            }
        }
        stack<int> s;
        for(int i=n;i>=1;i--){
            s.push(g[i][pos]);
            pos=t[i][pos];
        }
        while(!s.empty()){
            int x=s.top();
            s.pop();
            printf("%d ",x);
        }
        return 0;
    }

    T3 下棋

    题目大意:给定$n$个大小为$1 imes l_i$的棋盘,两个人轮流在上面下棋。规定落子的地方不能有棋子,且不能与其它棋子相邻。问是否先手必胜。

    傻逼题。对$sg$函数打表发现循环节为$34$,直接判一下即可……

    代码:

    #include<bits/stdc++.h>
    #define reg register
    #define getchar() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?EOF:*S++)
    char B[1<<15],*S=B,*T=B;
    int read()
    {
        reg int s=0,f=1; reg char ch;
        for(;(ch=getchar())<'0'||ch>'9';ch=='-'?f=-f:0);
        for(;ch>='0'&&ch<='9';s=s*10+ch-'0',ch=getchar());
        return s*f;
    }
    int sg[110]={0,1},vis[110];
    int SG(reg int x) {return x<=51?sg[x]:sg[51+(x-51)%34+(!((x-51)%34)?34:0)];}
    int main()
    {
        for(reg int i=2,k;i<=85;++i)
        {
            vis[sg[i-2]]=i;
            for(reg int j=0;j<=i-3;++j)
                vis[sg[j]^sg[i-3-j]]=i;
            for(k=0;vis[k]==i;++k);
            sg[i]=k;
        }
        for(reg int t=read();t--;)
        {
            reg int ans=0;
            for(reg int n=read();n--;ans^=SG(read()));
            puts(ans?"Alice":"Bob");
        }
        return 0;
    }

    T4 魔方

    题目大意:给定一个三阶魔方,每个格子上有一个数字。给定其平面展开图。对于三阶魔方有$18$种旋转操作。问经过若干次旋转之后的展开图。

    这题太TM傻逼了。没有任何技术含量,就纯粹模拟。让我当了一会码农……

    如果旋转的不是中间的部分也会带着旁边的一面旋转……还有注意格子与格子的对应关系(说多了都是泪QAQ)。

    没什么多说的,直接上代码……

    代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    int a[7][5][5],tmp[7][5][5];
    char s[10005];
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    //1:3->1->6->5->3
    inline void r1(int j)
    {
        for (int i=1;i<=3;i++)
        {
            a[1][i][j]=tmp[6][i][j];
            a[3][i][j]=tmp[1][i][j];
            a[5][i][j]=tmp[3][i][j];
            a[6][i][j]=tmp[5][i][j];
        }
        if (j==2) return;
        if (j==1)
        {
            a[2][1][3]=tmp[2][1][1];a[2][2][3]=tmp[2][1][2];a[2][3][3]=tmp[2][1][3];
            a[2][1][2]=tmp[2][2][1];a[2][2][2]=tmp[2][2][2];a[2][3][2]=tmp[2][2][3];
            a[2][1][1]=tmp[2][3][1];a[2][2][1]=tmp[2][3][2];a[2][3][1]=tmp[2][3][3];
        }
        else
        {
            a[4][3][1]=tmp[4][1][1];a[4][2][1]=tmp[4][1][2];a[4][1][1]=tmp[4][1][3];
            a[4][3][2]=tmp[4][2][1];a[4][2][2]=tmp[4][2][2];a[4][1][2]=tmp[4][2][3];
            a[4][3][3]=tmp[4][3][1];a[4][2][3]=tmp[4][3][2];a[4][1][3]=tmp[4][3][3];
        }
    }
    inline void f1(int j)
    {
        for (int i=1;i<=3;i++)
        {
            a[5][i][j]=tmp[6][i][j];
            a[3][i][j]=tmp[5][i][j];
            a[1][i][j]=tmp[3][i][j];
            a[6][i][j]=tmp[1][i][j];
        }
        if (j==2) return;
        if (j==1)
        {
            a[2][1][1]=tmp[2][1][3];a[2][1][2]=tmp[2][2][3];a[2][1][3]=tmp[2][3][3];
            a[2][2][1]=tmp[2][1][2];a[2][2][2]=tmp[2][2][2];a[2][2][3]=tmp[2][3][2];
            a[2][3][1]=tmp[2][1][1];a[2][3][2]=tmp[2][2][1];a[2][3][3]=tmp[2][3][1];    
        }
        else
        {
            a[4][1][1]=tmp[4][3][1];a[4][1][2]=tmp[4][2][1];a[4][1][3]=tmp[4][1][1];
            a[4][2][1]=tmp[4][3][2];a[4][2][2]=tmp[4][2][2];a[4][2][3]=tmp[4][1][2];
            a[4][3][1]=tmp[4][3][3];a[4][3][2]=tmp[4][2][3];a[4][3][3]=tmp[4][1][3];
        }
    }
    inline void r2(int j)
    {
        if (j==1)
        {
            a[4][1][1]=tmp[1][3][1];a[4][2][1]=tmp[1][3][2];a[4][3][1]=tmp[1][3][3];
            a[1][3][3]=tmp[2][1][3];a[1][3][2]=tmp[2][2][3];a[1][3][1]=tmp[2][3][3];
            a[2][1][3]=tmp[5][1][1];a[2][2][3]=tmp[5][1][2];a[2][3][3]=tmp[5][1][3];
            a[5][1][3]=tmp[4][1][1];a[5][1][2]=tmp[4][2][1];a[5][1][1]=tmp[4][3][1];
        }
        if (j==2)
        {
            a[4][1][2]=tmp[1][2][1];a[4][2][2]=tmp[1][2][2];a[4][3][2]=tmp[1][2][3];
            a[1][2][3]=tmp[2][1][2];a[1][2][2]=tmp[2][2][2];a[1][2][1]=tmp[2][3][2];
            a[2][1][2]=tmp[5][2][1];a[2][2][2]=tmp[5][2][2];a[2][3][2]=tmp[5][2][3];
            a[5][2][3]=tmp[4][1][2];a[5][2][2]=tmp[4][2][2];a[5][2][1]=tmp[4][3][2];
        }
        if (j==3)
        {
            a[4][1][3]=tmp[1][1][1];a[4][2][3]=tmp[1][1][2];a[4][3][3]=tmp[1][1][3];
            a[1][1][3]=tmp[2][1][1];a[1][1][2]=tmp[2][2][1];a[1][1][1]=tmp[2][3][1];
            a[2][1][1]=tmp[5][3][1];a[2][2][1]=tmp[5][3][2];a[2][3][1]=tmp[5][3][3];
            a[5][3][3]=tmp[4][1][3];a[5][3][2]=tmp[4][2][3];a[5][3][1]=tmp[4][3][3];
        }
        if (j==2) return;
        if (j==1)
        {
            a[3][1][3]=tmp[3][1][1];a[3][2][3]=tmp[3][1][2];a[3][3][3]=tmp[3][1][3];
            a[3][1][2]=tmp[3][2][1];a[3][2][2]=tmp[3][2][2];a[3][3][2]=tmp[3][2][3];
            a[3][1][1]=tmp[3][3][1];a[3][2][1]=tmp[3][3][2];a[3][3][1]=tmp[3][3][3];
        }
        if (j==3)
        {
            a[6][3][1]=tmp[6][1][1];a[6][2][1]=tmp[6][1][2];a[6][1][1]=tmp[6][1][3];
            a[6][3][2]=tmp[6][2][1];a[6][2][2]=tmp[6][2][2];a[6][1][2]=tmp[6][2][3];
            a[6][3][3]=tmp[6][3][1];a[6][2][3]=tmp[6][3][2];a[6][1][3]=tmp[6][3][3];
        }
    }
    //2:4->1->2->5->4
    inline void f2(int j)
    {
        if (j==1)
        {
            a[1][3][1]=tmp[4][1][1];a[1][3][2]=tmp[4][2][1];a[1][3][3]=tmp[4][3][1];
            a[2][1][3]=tmp[1][3][3];a[2][2][3]=tmp[1][3][2];a[2][3][3]=tmp[1][3][1];
            a[5][1][1]=tmp[2][1][3];a[5][1][2]=tmp[2][2][3];a[5][1][3]=tmp[2][3][3];
            a[4][1][1]=tmp[5][1][3];a[4][2][1]=tmp[5][1][2];a[4][3][1]=tmp[5][1][1];
        }
        if (j==2)
        {
            a[1][2][1]=tmp[4][1][2];a[1][2][2]=tmp[4][2][2];a[1][2][3]=tmp[4][3][2];
            a[2][1][2]=tmp[1][2][3];a[2][2][2]=tmp[1][2][2];a[2][3][2]=tmp[1][2][1];
            a[5][2][1]=tmp[2][1][2];a[5][2][2]=tmp[2][2][2];a[5][2][3]=tmp[2][3][2];
            a[4][1][2]=tmp[5][2][3];a[4][2][2]=tmp[5][2][2];a[4][3][2]=tmp[5][2][1];
        }
        if (j==3)
        {
            a[1][1][1]=tmp[4][1][3];a[1][1][2]=tmp[4][2][3];a[1][1][3]=tmp[4][3][3];
            a[2][1][1]=tmp[1][1][3];a[2][2][1]=tmp[1][1][2];a[2][3][1]=tmp[1][1][1];
            a[5][3][1]=tmp[2][1][1];a[5][3][2]=tmp[2][2][1];a[5][3][3]=tmp[2][3][1];
            a[4][1][3]=tmp[5][3][3];a[4][2][3]=tmp[5][3][2];a[4][3][3]=tmp[5][3][1];
        }
        if (j==2) return;
        if (j==1)
        {
            a[3][1][1]=tmp[3][1][3];a[3][1][2]=tmp[3][2][3];a[3][1][3]=tmp[3][3][3];
            a[3][2][1]=tmp[3][1][2];a[3][2][2]=tmp[3][2][2];a[3][2][3]=tmp[3][3][2];
            a[3][3][1]=tmp[3][1][1];a[3][3][2]=tmp[3][2][1];a[3][3][3]=tmp[3][3][1];
        }
        if (j==3)
        {
            a[6][1][1]=tmp[6][3][1];a[6][1][2]=tmp[6][2][1];a[6][1][3]=tmp[6][1][1];
            a[6][2][1]=tmp[6][3][2];a[6][2][2]=tmp[6][2][2];a[6][2][3]=tmp[6][1][2];
            a[6][3][1]=tmp[6][3][3];a[6][3][2]=tmp[6][2][3];a[6][3][3]=tmp[6][1][3];
        }
    }
    //3:3->4->6->2->3
    inline void f3(int i)
    {
        for (int j=1;j<=3;j++)
        {
            a[4][i][j]=tmp[3][i][j];
            a[6][3-i+1][3-j+1]=tmp[4][i][j];
            a[2][i][j]=tmp[6][3-i+1][3-j+1];
            a[3][i][j]=tmp[2][i][j];
        }
        if (i==2) return;
        if (i==1)
        {
            a[1][1][1]=tmp[1][1][3];a[1][1][2]=tmp[1][2][3];a[1][1][3]=tmp[1][3][3];
            a[1][2][1]=tmp[1][1][2];a[1][2][2]=tmp[1][2][2];a[1][2][3]=tmp[1][3][2];
            a[1][3][1]=tmp[1][1][1];a[1][3][2]=tmp[1][2][1];a[1][3][3]=tmp[1][3][1];
        }
        else
        {
            a[5][1][1]=tmp[5][3][1];a[5][1][2]=tmp[5][2][1];a[5][1][3]=tmp[5][1][1];
            a[5][2][1]=tmp[5][3][2];a[5][2][2]=tmp[5][2][2];a[5][2][3]=tmp[5][1][2];
            a[5][3][1]=tmp[5][3][3];a[5][3][2]=tmp[5][2][3];a[5][3][3]=tmp[5][1][3];
        }
    }
    inline void r3(int i)
    {
        for (int j=1;j<=3;j++)
        {
            a[3][i][j]=tmp[4][i][j];
            a[4][i][j]=tmp[6][3-i+1][3-j+1];
            a[6][3-i+1][3-j+1]=tmp[2][i][j];
            a[2][i][j]=tmp[3][i][j];
        }
        if (i==2) return;
        if (i==1)
        {
            a[1][1][3]=tmp[1][1][1];a[1][2][3]=tmp[1][1][2];a[1][3][3]=tmp[1][1][3];
            a[1][1][2]=tmp[1][2][1];a[1][2][2]=tmp[1][2][2];a[1][3][2]=tmp[1][2][3];
            a[1][1][1]=tmp[1][3][1];a[1][2][1]=tmp[1][3][2];a[1][3][1]=tmp[1][3][3];
        }
        if (i==3)
        {
            a[5][3][1]=tmp[5][1][1];a[5][2][1]=tmp[5][1][2];a[5][1][1]=tmp[5][1][3];
            a[5][3][2]=tmp[5][2][1];a[5][2][2]=tmp[5][2][2];a[5][1][2]=tmp[5][2][3];
            a[5][3][3]=tmp[5][3][1];a[5][2][3]=tmp[5][3][2];a[5][1][3]=tmp[5][3][3];
        }
    }
    inline void output()
    {
        for (int i=1;i<=3;i++)
            printf("%d %d %d 
    ",a[1][i][1],a[1][i][2],a[1][i][3]);
        for (int i=1;i<=3;i++)
        {
            printf("%d %d %d ",a[2][i][1],a[2][i][2],a[2][i][3]);
            printf("%d %d %d ",a[3][i][1],a[3][i][2],a[3][i][3]);
            printf("%d %d %d 
    ",a[4][i][1],a[4][i][2],a[4][i][3]);
        }
        for (int i=1;i<=3;i++)
            printf("%d %d %d 
    ",a[5][i][1],a[5][i][2],a[5][i][3]);
        for (int i=1;i<=3;i++)
            printf("%d %d %d 
    ",a[6][i][1],a[6][i][2],a[6][i][3]);
    }
    int main()
    {
        for (int i=1;i<=3;i++)
            for (int j=1;j<=3;j++) a[1][i][j]=read();
        for (int i=1;i<=3;i++)
            for (int j=1;j<=9;j++)
            {
                if (j<=3) a[2][i][j]=read();
                if (j>3&&j<=6) a[3][i][j-3]=read();
                if (j>6&&j<=9) a[4][i][j-6]=read();
            }
        for (int i=1;i<=6;i++)
            for (int j=1;j<=3;j++)
            {
                if (i<=3) a[5][i][j]=read();
                else a[6][i-3][j]=read();
            }
        memcpy(tmp,a,sizeof(tmp));
        scanf("%s",s+1);
        int len=strlen(s+1);
        for (int i=1;i<=len;i++)
        {
            if (s[i]=='a'||s[i]=='b'||s[i]=='c') f1(s[i]-'a'+1);
            if (s[i]=='A'||s[i]=='B'||s[i]=='C') r1(s[i]-'A'+1);
            if (s[i]=='d'||s[i]=='e'||s[i]=='f') f2(s[i]-'d'+1);
            if (s[i]=='D'||s[i]=='E'||s[i]=='F') r2(s[i]-'D'+1);
            if (s[i]=='h'||s[i]=='i'||s[i]=='j') f3(s[i]-'h'+1);
            if (s[i]=='H'||s[i]=='I'||s[i]=='J') r3(s[i]-'H'+1);
            memcpy(tmp,a,sizeof(tmp));
        }
        output();
        return 0;
    }
  • 相关阅读:
    java wait 与 notify sleep
    java线程安全总结
    ubuntu安装遇到的问题
    python时间处理函数
    js获取当前时间
    sql如何将同个字段不同值打印在一行
    django models数据类型
    django上传图片和文字记录
    django form使用学习记录
    django中request对象详解(转载)
  • 原文地址:https://www.cnblogs.com/Invictus-Ocean/p/13837532.html
Copyright © 2011-2022 走看看