zoukankan      html  css  js  c++  java
  • 2013金山西山居创意游戏程序挑战赛——复赛(1) HDU 4557 非诚勿扰 HDU 4558 剑侠情缘 HDU 4559 涂色游戏 HDU 4560 我是歌手

    今天的比赛。。。。。速度还是慢了。。。

    无缘无故错误提交好多次。。哭了。。。。

    比较简单:

    A题:HDU 4557 

    非诚勿扰

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4557

    暴力胡搞,水题:

    //============================================================================
    // Name        : A.cpp
    // Author      : 
    // Version     :
    // Copyright   : Your copyright notice
    // Description : Hello World in C++, Ansi-style
    //============================================================================
    
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <map>
    #include <set>
    #include <string>
    #include <math.h>
    using namespace std;
    const int MAXN=1010;
    char str[MAXN][100];
    int a[MAXN];
    bool used[MAXN];
    
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
    //    freopen("out.txt","w",stdout);
        int T;
        int n;
        int top;
        scanf("%d",&T);
        int iCase=0;
        while(T--)
        {
            iCase++;
            printf("Case #%d:\n",iCase);
            scanf("%d",&n);
            char op[20];
            memset(used,false,sizeof(used));
            int num=0;
            top=0;
            while(n--)
            {
                scanf("%s",&op);
                if(op[0]=='A')
                {
                    scanf("%s%d",&str[top],&a[top]);
                    top++;
                    num++;
                    printf("%d\n",num);
                }
                else
                {
                    int tmp;
                    scanf("%d",&tmp);
                    int k=-1;
                    for(int i=0;i<top;i++)
                        if(!used[i]&&a[i]>=tmp)
                            if(k==-1||(a[i]<a[k]))
                            {
                                k=i;
                            }
                    if(k==-1)printf("WAIT...\n");
                    else
                    {
                        printf("%s\n",str[k]);
                        used[k]=true;
                        num--;
                    }
                }
            }
        }
    
        return 0;
    }
    A

    B题:HDU 4558 

    剑侠情缘

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4558

    DP

    一开始状态想错了。。只要记录差值就可以的

    dp[i][j][x]表示在(i,j)这个点,差值为x

    转移的时候把差值取相反数就实现轮流了

    dp[i][j][x]表示(i,j)出发。人和剑的能量的差值为x.可以得到的相反数

    那么状态转移的时候,首先x+=这个点的值。。如果这个时候x==0表示想到了,那么dp[i][j][x]++

    然后往下和往右转移。下一步是更新剑了。所以对x取相反数

    //============================================================================
    // Name        : B.cpp
    // Author      : 
    // Version     :
    // Copyright   : Your copyright notice
    // Description : Hello World in C++, Ansi-style
    //============================================================================
    
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <map>
    #include <set>
    #include <string>
    #include <math.h>
    using namespace std;
    const int MAXN=500;
    char str[MAXN][MAXN];
    const int MOD=1e9+7;
    int dp[MAXN][MAXN][11];
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
    //    freopen("out.txt","w",stdout);
        int T;
        int n,m;
        scanf("%d",&T);
        int iCase=0;
        while(T--)
        {
            iCase++;
            printf("Case %d: ",iCase);
            scanf("%d%d",&n,&m);
            for(int i=0;i<n;i++)scanf("%s",str[i]);
            int ans=0;
            memset(dp,0,sizeof(dp));
            for(int i=n-1;i>=0;i--)
            {
                for(int j=m-1;j>=0;j--)
                {
                    for(int x=0;x<11;x++)
                        {
                            int tmp=x+(str[i][j]-'0');
                            tmp=(tmp)%11;
                            int tmp2=(11-tmp)%11;
                            if(i<n-1)
                            {
                                dp[i][j][x]+=dp[i+1][j][tmp2];
                            }
                            dp[i][j][x]%=MOD;
                            if(j<m-1)dp[i][j][x]+=dp[i][j+1][tmp2];
                            dp[i][j][x]%=MOD;
                            if(tmp==0)
                            {
                                dp[i][j][x]++;
                                dp[i][j][x]%=MOD;
                            }
                            if(x==0)
                            {
                                ans+=dp[i][j][x];
                                ans%=MOD;
                            }
                        }
                }
            }
            printf("%d\n",ans);
        }
        return 0;
    }
    B

    C:HDU 4559 

    涂色游戏

    博弈题:

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4559

    SG函数计算。

    SG函数很高深。。。

    想了好久才会。

    其实1*1的点sg值就是1

    sg[i]表示2*i 的sg值。

    sg[i]求解就是普通的SG函数了。

    然后进行分段做。

    分段;

    //============================================================================
    // Name        : C.cpp
    // Author      : 
    // Version     :
    // Copyright   : Your copyright notice
    // Description : Hello World in C++, Ansi-style
    //============================================================================
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <map>
    #include <set>
    #include <string>
    #include <math.h>
    using namespace std;
    const int MAXN=5000;
    int sg[MAXN];
    bool vis[MAXN];
    int mex(int x)
    {
        if(sg[x]!=-1)return sg[x];
        memset(vis,false,sizeof(vis));
        for(int i=0;x-1-i>=i;i++)
        {
            int tmp=mex(i)^mex(x-1-i)^1;
            vis[tmp]=true;
        }
        for(int i=0;x-2-i>=i;i++)
        {
            int tmp=mex(i)^mex(x-2-i);
            vis[tmp]=true;
        }
        for(int i=0;;i++)
            if(!vis[i])
            {
                sg[x]=i;
                break;
            }
        return sg[x];
    }
    bool g[2][MAXN];
    int main()
    {
    //    freopen("in.txt","r",stdin);
    //    freopen("out.txt","w",stdout);
        memset(sg,-1,sizeof(sg));
        sg[0]=0;
        for(int i=1;i<5000;i++)
            sg[i]=mex(i);
        int T;
        scanf("%d",&T);
        int iCase=0;
        while(T--)
        {
            int n,m;
            scanf("%d%d",&n,&m);
            memset(g,false,sizeof(g));
            int u,v;
            while(m--)
            {
                scanf("%d%d",&u,&v);
                u--;v--;
                g[u][v]=true;
            }
            int len=0;
            int ans=0;
            for(int i=0;i<n;i++)
            {
                if(g[0][i]||g[1][i])
                {
                    ans^=sg[len];
                    len=0;
                    if(g[0][i]&&g[1][i])continue;
                    ans^=1;
                }
                else len++;
            }
            ans^=sg[len];
            iCase++;
            if(ans)printf("Case %d: Alice\n",iCase);
            else printf("Case %d: Bob\n",iCase);
        }
        return 0;
    }
    C

    D:HDU 4560

    我是歌手

    最大流+二分

    链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=4560

     这个题目的建图比较常规。

    N个歌手编号为1~N

    M种歌曲,拆点。编号分别为N+1~N+M,N+M+1~N+2*M

    源点为0,汇点为N+2*M+1  总共N+2*M+2个点。

    N+i 和  N+M+i  之间连权值为K的边,作为限制。

    对于i, j  如果i对j擅长,那么连边 i -> N+M+j

    否则连边 i -> N+j 这样就可以限制了。

    然后是二分答案。

    0~(1~N)之间,连边 mid .

    (N+M+1~N+2*M)与N+2*M+1之间也连边mid

    然后判断mid*N和最大流是不是相当。

     然后就是最大流模板题了。

    //============================================================================
    // Name        : D.cpp
    // Author      : 
    // Version     :
    // Copyright   : Your copyright notice
    // Description : Hello World in C++, Ansi-style
    //============================================================================
    
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <map>
    #include <set>
    #include <string>
    #include <math.h>
    using namespace std;
    
    const int MAXN=1100;
    int maze[MAXN][MAXN];
    int gap[MAXN],dis[MAXN],pre[MAXN],cur[MAXN];
    int flow[MAXN][MAXN];//存最大流的容量
    int sap(int start,int end,int nodenum)
    {
        memset(cur,0,sizeof(cur));
        memset(dis,0,sizeof(dis));
        memset(gap,0,sizeof(gap));
        memset(flow,0,sizeof(flow));
        int u=pre[start]=start,maxflow=0,aug=-1;
        gap[0]=nodenum;
        while(dis[start]<nodenum)
        {
            loop:
              for(int v=cur[u];v<nodenum;v++)
                if(maze[u][v]-flow[u][v] && dis[u]==dis[v]+1)
                {
                    if(aug==-1 || aug>maze[u][v]-flow[u][v])aug=maze[u][v]-flow[u][v];
                    pre[v]=u;
                    u=cur[u]=v;
                    if(v==end)
                    {
                        maxflow+=aug;
                        for(u=pre[u];v!=start;v=u,u=pre[u])
                        {
                            flow[u][v]+=aug;
                            flow[v][u]-=aug;
                        }
                        aug=-1;
                    }
                    goto loop;
                }
                int mindis=nodenum-1;
                for(int v=0;v<nodenum;v++)
                   if(maze[u][v]-flow[u][v]&&mindis>dis[v])
                   {
                       cur[u]=v;
                       mindis=dis[v];
                   }
                if((--gap[dis[u]])==0)break;
                gap[dis[u]=mindis+1]++;
                u=pre[u];
        }
        return maxflow;
    }
    
    bool used[MAXN][MAXN];
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
    //    freopen("out.txt","w",stdout);
        int T;
        int N,M,L,K;
        scanf("%d",&T);
        int iCase=0;
        while(T--)
        {
            iCase++;
            scanf("%d%d%d%d",&N,&M,&L,&K);
            memset(maze,0,sizeof(maze));
            int u,v;
            memset(used,false,sizeof(used));
            while(L--)
            {
                scanf("%d%d",&u,&v);
                used[u][v]=true;
            }
            for(int i=N+1;i<=N+M;i++)maze[i][i+M]=K;
            for(int i=1;i<=N;i++)
                for(int j=1;j<=M;j++)
                {
                    if(used[i][j])
                    {
                        maze[i][j+N+M]=1;
                    }
                    else maze[i][j+N]=1;
                }
            int ans=0;
            int l=0,r=M;
            while(l<=r)
            {
                int mid=(l+r)/2;
                for(int i=1;i<=N;i++)maze[0][i]=mid;
                for(int i=N+M+1;i<=N+2*M;i++)maze[i][N+2*M+1]=mid;
                if(sap(0,N+2*M+1,N+2*M+2)==mid*N)
                {
                    ans=mid;
                    l=mid+1;
                }
                else r=mid-1;
            }
            printf("Case %d: %d\n",iCase,ans);
        }
    
    
        return 0;
    }
    D
    人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想
  • 相关阅读:
    Effective C++ 笔记 —— Item 26: Postpone variable definitions as long as possible.
    Effective C++ 笔记 —— Item 25: Consider support for a non-throwing swap.
    Effective C++ 笔记 —— Item 24: Declare non-member functions when type conversions should apply to all parameters.
    Effective C++ 笔记 —— Item 23: Prefer non-member non-friend functions to member functions.
    Effective C++ 笔记 —— Item 22: Declare data members private.
    Effective C++ 笔记 —— Item 21: Don't try to return a reference when you must return an object.
    Effective C++ 笔记 —— Item 20: Prefer pass-by-reference-to-const to pass-by-value.
    Effective C++ 笔记 —— Item 19: Treat class design as type design.
    Effective C++ 笔记 —— Item 18: Make interfaces easy to use correctly and hard to use incorrectly.
    eureka server集群信息同步
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3097767.html
Copyright © 2011-2022 走看看