• 9.30 noip模拟试题


     

    时限均为1s,内存 256MB

    1、某种密码(password.*)

        关于某种密码有如下描述:某种密码的原文A是由N个数字组成,而密文B是一个长度为N的01数串,原文和密文的关联在于一个钥匙码KEY。若KEY=∑▒〖Ai*Bi〗,则密文就是原文的一组合法密码。

           现在有原文和钥匙码,请编一个程序来帮助他统计到底有多少个符合条件的密文。

    【输入数据】

           第一行两个数N,KEY,意义同题目描述;

           第二行N个数表示原文A,意义同题目描述。

    【输出数据】

           一个数ANS,表示对于原文A和KEY,有多少组可行的密文B。

    【输入样例】

    3 2

    1 1 2

    【输出样例】

    2

    【样例说明】

    密文110,1*1+1*1+0*2=2

    密文001,0*1+0*1+1*2=2

    一共两组可行的密文。

    【数据约定】

    60%数据满足N<=25

    100%数据满足N<=40,-maxlongint<=∑▒Ai<=maxlongint

     暴力+hash

    /*蒟蒻用map*/
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<map>
    #define ll long long
    using namespace std;
    long long n,k,N,a[50],falg,ans;
    map<long long,long long>p;
    void Dfs(long long now,long long s){
        if(now==N+1){
            if(!falg)p[s]++;
            else ans+=p[k-s];
            return;
        }
        Dfs(now+1,s);
        Dfs(now+1,s+a[now]);
    }
    int main()
    {
        freopen("password.in","r",stdin);
        freopen("password.out","w",stdout);
        cin>>n>>k;
        for(long long i=1;i<=n;i++)cin>>a[i];
        N=n/2;Dfs(1,0);
        falg=1;N=n;Dfs(n/2+1,0);
        cout<<ans;
        return 0;
    }
    View Code

    2、球的序列(formation.*)

       N个编号为1-n的球,每个球都有唯一的编号。这些球被排成两种序列,分别为A、B序列,现在需要重新寻找一个球的序列l,对于这个子序列l中任意的两个球,要求j,k(j<k),都要求满足lj在A中位置比lk在A中位置靠前,却lj在B中位置比lk在B中位置靠前,请你计算这个子序列l的最大长度。

    输入:

    第一行一个整数,表示N。

    第二行N个整数,表示A序列。

    第三行N个整数,表示B序列。

    样例输入

    5

    1 2 4 3 5

    5 2 3 4 1

    //5 2 4 3 1

    样例输出

    2

    样例说明

    L可以是{2,3},也可以是{2,4}

    数据范围:

    40% N<=5000

    100% N<=50000

    暴力LCS 40

    #include<cstdio>
    #define maxn 10010
    using namespace std;
    int n,a[maxn],b[maxn];
    short f[maxn][maxn];
    int init(){
        int x=0;char s=getchar();
        while(s<'0'||s>'9')s=getchar();
        while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
        return x;
    }
    short max(short x,short y){
        return x>y?x:y;
    }
    int main()
    {
        freopen("formation.in","r",stdin);
        freopen("formation.out","w",stdout);
        n=init();
        for(int i=1;i<=n;i++)a[i]=init();
        for(int i=1;i<=n;i++)b[i]=init();
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(a[i]==b[j])f[i][j]=f[i-1][j-1]+1;
                else f[i][j]=max(f[i-1][j],f[i][j-1]);
        printf("%d
    ",f[n][n]);
        return 0;
    }
    View Code

    转化成LIS

    /*并不难的题没好好想想~~*/
    #include<cstdio>
    #include<algorithm>
    #define maxn 50010
    using namespace std;
    int n,a[maxn],b[maxn],c[maxn],r;
    int init(){
        int x=0;char s=getchar();
        while(s<'0'||s>'9')s=getchar();
        while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
        return x;
    }
    int max(int x,int y){
        return x>y?x:y;
    }
    void LIS(){
        for(int i=1;i<=n;i++){
            int x=b[i];
            if(x>c[r]){
                c[++r]=x;
                continue;
            }
            int p=lower_bound(c+1,c+1+r,x)-c;
            c[p]=x;
        }
    }
    int main()
    {
        //freopen("formation.in","r",stdin);
        //freopen("formation.out","w",stdout);
        n=init();int x;
        for(int i=1;i<=n;i++){
            x=init();a[x]=i;
        }
        for(int i=1;i<=n;i++){
            x=init();b[i]=a[x];
        }
        LIS();
        printf("%d
    ",r);
        return 0;
    }
    View Code

    3大逃亡(escape.*)

    给出数字N(1<=N<=10000),X(1<=x<=1000),Y(1<=Y<=1000),代表有N个敌人分布一个X行Y列的矩阵上,矩形的行号从0到X-1,列号从0到Y-1再给出四个数字x1,y1,x2,y2,代表你要从点(x1,y1)移到(x2,y2)。在移动的过程中你当然希望离敌人的距离的最小值最大化,现在请求出这个值最大可以为多少,以及在这个前提下,你最少要走多少步才可以回到目标点。注意这里距离的定义为两点的曼哈顿距离,即某两个点的坐标分为(a,b),(c,d),那么它们的距离为|a-c|+|b-d|。

    输入:

    第一行给出数字N,X,Y

    第二行给出x1,y1,x2,y2

    下面将有N行,给出N个敌人所在的坐标

    输出:

    在一行内输出你离敌人的距离及在这个距离的限制下,你回到目标点最少要移动多少步。

    Sample input

    2 5 6

    0 0 4 0

    2 1

    2 3

    Sample output

    2 14

     

    /*本来能A的 但写wa了 这种题又没法拍 哎QAQ*/
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define maxn 1010
    using namespace std;
    int n,m,k,f[maxn][maxn],dis[maxn][maxn];
    int x1,x2,y1,y2,ans,step;
    struct node{
        int x,y,s;
    };
    int xx[4]={0,0,1,-1};
    int yy[4]={1,-1,0,0};
    queue<node>q;
    void Bfs(){
        while(!q.empty()){
            node t=q.front();q.pop();
            dis[t.x][t.y]=t.s;
            for(int i=0;i<4;i++){
                int nx=t.x+xx[i];
                int ny=t.y+yy[i];
                if(nx>0&&nx<=n&&ny>0&&ny<=m&&f[nx][ny]==0){
                    f[nx][ny]=1;dis[nx][ny]=t.s+1;
                    q.push((node){nx,ny,t.s+1});
                }
            }
        }
    }
    int Judge(int S){
        if(dis[x1][y1]<S)return -1;//这里没考虑到 
        memset(f,0,sizeof(f));
        f[x1][y1]=1;
        while(!q.empty())q.pop();
        q.push((node){x1,y1,0});
        while(!q.empty()){
            node t=q.front();q.pop();
            if(t.x==x2&&t.y==y2)
                return t.s;//开始wa的时候是返回01 并且直接改 
            for(int i=0;i<4;i++){
                int nx=t.x+xx[i];
                int ny=t.y+yy[i];
                if(nx>0&&nx<=n&&ny>0&&ny<=m&&f[nx][ny]==0&&dis[nx][ny]>=S){
                    f[nx][ny]=1;
                    q.push((node){nx,ny,t.s+1});
                }
            }
        }
        return -1;
    }
    int main()
    {
        freopen("escape.in","r",stdin);
        freopen("escape.out","w",stdout);
        scanf("%d%d%d",&k,&n,&m);
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        x1++;x2++;y1++;y2++;
        int x,y;
        memset(dis,127/3,sizeof(dis));
        for(int i=1;i<=k;i++){
            scanf("%d%d",&x,&y);
            x++;y++;
            q.push((node){x,y,0});
            f[x][y]=1;dis[x][y]=0;
        }
        Bfs();
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++)
                printf("%d ",dis[i][j]);
            printf("
    ");
        }
        int l=0,r=maxn*maxn;
        while(l<=r){
            int mid=(l+r)/2;
            int tmp=Judge(mid);
            if(tmp!=-1){
                l=mid+1;ans=mid;
                step=tmp;
            }
            else r=mid-1;
        }
        printf("%d %d
    ",ans,step);
        return 0;
    }
    View Code
  • 相关阅读:
    撩妹技能 get,教你用 canvas 画一场流星雨
    git详细使用教程入门到精通(史上最全的git教程)
    Google Performance工具,你还不会用?Git走起。
    使用PIE.htc让万恶的IE内核浏览器IE678支持CSS3部分属性
    HTML编码规范
    Canvas制作的下雨动画
    Flex 布局教程:语法和实例
    CSS编码规范
    奇葩程序写的神一样的注释,被老板看见会不会开出呢?
    Vertical-Align你应该知道的一切
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5924813.html
Copyright © 2020-2023  润新知