• UVaOJ 112道题目-数据结构


    1、110201/10038 Jolly Jumpers (快乐的跳跃者)

    即相邻数字差的绝对值覆盖1~n-1,注意 单词 seccesive,take on

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<ctype.h>
    using namespace std;
    int arr[3005];
    bool t[3005];
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            int i;
            for(i=0;i<n;i++)
            {
                scanf("%d",&arr[i]);
            }
            bool flag=true;
            memset(t,0,sizeof(t));
            for(i=1;i<n;i++)
            {
                int f=abs(arr[i]-arr[i-1]);
                if(f>=1&&f<=n-1)
                {
                    t[f]=1;
                }
                else
                {
                    flag=false;
                    break;
                }
            }
            for(i=1;i<n;i++)
            {
                if(t[i]==0)
                {
                    flag=false;
                    break;
                }
            }
            if(flag)
                printf("Jolly
    ");
            else
                printf("Not jolly
    ");
        }
        return 0;
    }
    View Code

     2、110202/10315 Poker Hands (扑克牌型)

    此题为德州扑克,又名港式5张,相同类型比较时注意当相同张数>=3时,只比较相同张数的牌即可

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<ctype.h>
    using namespace std;
    char p1[5][5],p2[5][5];
    char poker[20]={'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
    int cnt[2][20];
    int tot[20];
    int dig[2][10];
    int ans1[10][10];
    int ans2[10][10];
    int GetNum(char a)
    {
        int i;
        for(i=0;i<13;i++)
        {
            if(poker[i]==a)return i;
        }
    }
    bool cmp(int a,int b)
    {
        return  a<b;
    }
    int GetType(char p[][5],int type)
    {
        int i;
        bool tf=true,df=true;
        dig[type][0]=GetNum(p[0][0]);
        for(i=1;i<5;i++)
        {
            dig[type][i]=GetNum(p[i][0]);
            if(p[i][1]!=p[i-1][1])
            {
                tf=false;
            }
        }
        sort(dig[type],dig[type]+5,cmp);
        for(i=1;i<5;i++)
        {
            if(dig[type][i]!=dig[type][i-1]+1)
            {
                df=false;
                break;
            }
        }
        if(tf&&df)return 1;
        if(tf)return 4;
        if(df)return 5;
        memset(cnt,0,sizeof(cnt));
        memset(tot,0,sizeof(tot));
        for(i=0;i<5;i++)
        {
            cnt[type][dig[type][i]]++;
        }
        for(i=0;i<13;i++)
        {
            tot[cnt[type][i]]++;
        }
        if(tot[4]==1)return 2;
        if(tot[3]==1&&tot[2]==1)return 3;
        if(tot[3]==1)return 6;
        if(tot[2]==2)return 7;
        if(tot[2]==1)return 8;
        return 9;
    }
    void fun(int ans[][10],int type)
    {
        int i,j;
        for(i=0;i<10;i++)
            for(j=0;j<10;j++)ans[i][j]=-1;
        memset(tot,0,sizeof(tot));
        for(i=0;i<5;i++)
        {
            tot[dig[type][i]]++;
        }
        int cnt=0;
        for(i=12;i>=0;i--)
        {
            if(tot[i]!=0)
            {
                cnt+=tot[i];
                if(ans[tot[i]][0]==-1)
                    ans[tot[i]][0]=1;
                else ans[tot[i]][0]++;
                int t=ans[tot[i]][0];
                ans[tot[i]][t]=i;
                if(cnt==5)
                    return;
            }
        }
    }
    int main()
    {
        int i=0,j;
        while(scanf("%s",p1[0])!=EOF)
        {
            for(i=1;i<5;i++)scanf("%s",p1[i]);
            for(i=0;i<5;i++)scanf("%s",p2[i]);
            int t1=GetType(p1,0);
            int t2=GetType(p2,1);
            int W=-1;
            if(t1<t2)printf("Black wins.
    ");
            else if(t1>t2)printf("White wins.
    ");
            else
            {
                fun(ans1,0);
                fun(ans2,1);
                bool find=false;
                for(i=5;i>=1&&!find;i--)
                {
                    if(ans1[i][0]!=-1&&ans2[i][0]!=-1)
                    {
                        for(j=1;j<=ans1[i][0];j++)
                        {
                            if(ans1[i][j]>ans2[i][j])
                            {
                                W=0;
                                find=true;
                                break;
                            }
                            else if(ans1[i][j]<ans2[i][j])
                            {
                                W=1;
                                find=true;
                                break;
                            }
                        }
                        if(i>=3)break;
                    }
                }
                if(W==0)printf("Black wins.
    ");
                else if(W==1)printf("White wins.
    ");
                else printf("Tie.
    ");
            }
        }
        return 0;
    }
    /*
    3H 3D 3S 9C KD 5C 5H 5S 5C 9H 
    7H 3H 4H 5H 6H 2S 3S 4S 5S 6S 
    6H 2D 4S 9C KD 6C 3H 4S 9C KH 
    */
    View Code

     3、110203/10050 Hartals (罢工)

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<ctype.h>
    using namespace std;
    int cnt[4000];
    int h[105];
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            memset(cnt,0,sizeof(cnt));
            int i,j,p,N;
            scanf("%d",&N);
            scanf("%d",&p);
            for(i=0;i<p;i++)
            {
                scanf("%d",&h[i]);
            }
            for(i=0;i<p;i++)
            {
                j=h[i];
                while(j<=N)
                {
                    cnt[j]++;
                    j+=h[i];
                }
            }
            int tot=0;
            for(j=1;j<=N;j++)
            {
                int t=j%7;
                if(t!=6&&t!=0)
                {
                    if(cnt[j]!=0)
                        tot++;
                }
            }
            printf("%d
    ",tot);
        }
        return 0;
    }
    View Code

     4、110204/843  Crypt Kicker (解密)

    非递归方式,需要考虑很多情况

    将单词按长度分类链接,若密文找不到匹配的单词则需要回溯

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<ctype.h>
    using namespace std;
    char word[1005][20];
    int nxt[1005];
    int h[20];
    int cur[85];
    char lin[85][20];
    int ch[85];
    char alp[100];
    int lett[100][20];
    int vis[100];
    int _alp[100];
    int _vis[100];
    void Read(int n)
    {
        int i;
        memset(h,-1,sizeof(h));
        memset(nxt,-1,sizeof(nxt));
        char tmp[100];
        for(i=0;i<n;i++)
        {
            gets(word[i]);
            int len=strlen(word[i]);
            nxt[i]=h[len];
            h[len]=i;
        }
    }
    void fun()
    {
        char tmp[100];
        while(gets(tmp)!=NULL)
        {
            int i,j,len=strlen(tmp),k=0,m=0,c,b;
            for(i=0;i<=len;i++)
            {
                if(tmp[i]==' '&&k==0)continue;
                if((tmp[i]==' '||i==len)&&k!=0)
                {
                    lin[m][k]='';
                    m++;
                    k=0;
                }
                else
                {
                    lin[m][k++]=tmp[i];
                }
            }
            memset(ch,0,sizeof(ch));
            for(i=0;i<26;i++)alp[i]='*';
            memset(cur,0,sizeof(cur));
            memset(lett,0,sizeof(lett));
            memset(vis,0,sizeof(vis));
            bool tag=false;
            bool end=false;
            for(i=0;i<m&&!end&&i>=0;i++)
            {
                len=strlen(lin[i]);
                bool flag=false;
                for(j=0;j<len;j++)
                {
                    if(alp[lin[i][j]-'a']=='*')
                        flag=true;
                }
                if(flag||tag)
                {
                    bool find=false;
                    k=h[len];
                    if(tag&&ch[i]==0)
                    {
                        i=i-2;
                        continue;
                    }
                    if(tag&&ch[i]==1)
                    {
                        for(j=1;j<=lett[i][0];j++)
                        {
                            c=lett[i][j];
                            b=alp[c]-'a';
                            alp[c]='*';
                            vis[b]=0;
                        }
                        lett[i][0]=0;
                    }
                    if(tag)k=nxt[cur[i]];
                    if(k==-1&&i==0)
                    {
                        end=true;
                        break;
                    }
                    for(;k!=-1&&!find;k=nxt[k])
                    {
                        for(j=0;j<len;j++)
                        {
                            c=lin[i][j]-'a';
                            b=word[k][j]-'a';
                            if(alp[c]!='*'&&alp[c]!=word[k][j])break;
                            if(alp[c]=='*'&&vis[b]==1)break;
                        }
                        if(j==len)
                        {
                            lett[i][0]=0;
                            for(j=0;j<26;j++)_alp[j]=alp[j];
                            for(j=0;j<26;j++)_vis[j]=vis[j];
                            for(j=0;j<len;j++)
                            {
                                c=lin[i][j]-'a';
                                b=word[k][j]-'a';
                                if(_alp[c]=='*')
                                {
                                    lett[i][0]++;
                                    lett[i][lett[i][0]]=c;
                                    if(_vis[b]==1)break;
                                }
                                else
                                {
                                    if(_alp[c]!=word[k][j])
                                    {
                                        break;
                                    }
                                }
                                _alp[c]=word[k][j];
                                _vis[b]=1;
                            }
                            if(j!=len)
                            {
                                continue;
                            }
                            else
                            {
                                for(j=0;j<len;j++)
                                {
                                    c=lin[i][j]-'a';
                                    alp[c]=word[k][j];
                                    c=word[k][j]-'a';
                                    vis[c]=1;                                                            
                                }
                            }
                            cur[i]=k;
                            find=true;
                            ch[i]=1;
                            tag=false;
                        }
                    }
                    if(!find)
                    {
                        i=i-2;
                        tag=true;
                    }
                }
                else
                {
                    bool find=false;
                    char str[100];
                    for(j=0;j<len;j++)
                    {
                        int c=lin[i][j]-'a';
                        str[j]=alp[c];
                    }
                    str[j]='';
                    for(k=h[len];k!=-1&&!find;k=nxt[k])
                    {
                        if(strcmp(str,word[k])==0)
                        {
                            find=true;
                            break;
                        }
                    }
                    if(!find)
                    {
                        i=i-2;
                        tag=true;
                    }
                    else
                    {
                        tag=false;
                        cur[i]=k;
                        ch[i]=0;
                    }
                }
            }
    
            len=strlen(tmp);
            for(i=0;i<len;i++)
            {
                if(tmp[i]>='a'&&tmp[i]<='z')
                {
                    if(end==true)
                    {
                        printf("*");
                        continue;
                    }
                    c=tmp[i]-'a';
                    printf("%c",alp[c]);
                }
                else 
                    printf("%c",tmp[i]);
            }
            printf("
    ");
        }
    }
    int main()
    {
        int n;
        char tmp[100];
        scanf("%d",&n);
        getchar();
        Read(n);
        fun();
        return 0;
    }
    /*
    6
    and
    dick
    jane
    puff
    spot
    yertde
    bjvg xsb hxsn xsb qymm xsb rqat xsb pnetfn
    
    6
    and
    dick
    jane
    puff
    spot
    yertle
    xxxx yyy zzzz www yyyy aaa bbbb ccc dddddd
    
    3
    aaad
    bbb
    cccc
    xxxx yyy zzzd 
    
    
    8
    and
    acq
    dick
    duop
    jane
    puff
    spot
    yertle
    bjvg xsb hxsn xsb qymm xsb    rqat xsb pnetfn
    
    1
    abbc
    abcd
    */
    View Code

      递归

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<ctype.h>
    using namespace std;
    char word[1005][100];
    int h[100],nxt[1005];
    char str[1005];
    char txt[100][20];
    int vis[100];
    char val[100];
    int xlen[100];
    int calc()
    {
        int i,j,len=strlen(str),m=0;
        for(i=0;i<len;i++)
        {
            if(i==0||(str[i-1]==' '&&str[i]!=' '))
            {
                j=0;
                while(i<len&&str[i]!=' ')txt[m][j++]=str[i++];
                txt[m][j]='';
                xlen[m]=j;
                m++;
            }
        }
        return m;
    }
    void DFS(int s,int m,char alp[],int vis[])
    {
        int len=xlen[s],i,j;
        if(s>=m)
        {
            for(i=0;i<26;i++)val[i]=alp[i];
            return;
        }
        char _alp[30];
        int _vis[30];
        for(i=h[len];i!=-1;i=nxt[i])
        {
            for(j=0;j<26;j++)
            {
                _alp[j]=alp[j];
                _vis[j]=vis[j];
            }
            for(j=0;j<len;j++)
            {
                int x=txt[s][j]-'a';
                int y=word[i][j]-'a';
                if(_alp[x]=='*')
                {
                    if(_vis[y]==1)break;
                    _alp[x]=word[i][j];
                    _vis[y]=1;
                }
                else
                {
                    if(_alp[x]!=word[i][j])break;
                }
            }
            if(j>=len)
            {
                DFS(s+1,m,_alp,_vis);
            }
        }
    }
    int main()
    {
        int n, i,len;
        char alp[30];
        scanf("%d",&n);
        getchar();
        memset(h,-1,sizeof(h));
        for(i=0;i<n;i++)
        {
            gets(word[i]);
            len=strlen(word[i]);
            nxt[i]=h[len];
            h[len]=i;
        }
        while(gets(str)!=NULL)
        {
            int m=calc();
            for(i=0;i<26;i++)
            {
                alp[i]='*';
                val[i]='*';
                vis[i]=0;
            }
            DFS(0,m,alp,vis);
            len=strlen(str);
            for(i=0;i<len;i++)
            {
                char c=str[i];
                if(c!=' ')
                {
                    printf("%c",val[c-'a']);
                }
                else 
                    printf(" ");
            }
            printf("
    ");
        }
    }
    /*
    
    */
    View Code

     5、(POJ)2469 Stack’em Up (完美洗牌术)

     i in position j means that the shuffle moves the ith card in the deck to position j.比较拗口,移动方向需注意,sa[0]=2,意思是第2个位置的数移动到第0位

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<ctype.h>
    using namespace std;
    int sa[105][100];
    int card[100],_card[100];
    char val[15][10]={"2", "3", "4","5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace"};
    char suit[5][10]={"Clubs", "Diamonds", "Hearts", "Spades"};
    int Getdig(char str[])
    {
        int i,len=strlen(str);
        int tot=0;
        for(i=0;i<len;i++)
        {
            if(isdigit(str[i]))tot=tot*10+str[i]-'0';
        }
        return tot;
    }
    int main()
    {
        int T,n,j,i;
        char num[100];
        //freopen("E:/a.txt","w",stdout);
        //scanf("%d",&T);
        while(scanf("%d",&n)!=EOF)
        {
            
            int tmp;
            for(i=1;i<=n;i++)
            {
                for(j=1;j<=52;j++)
                {
                    scanf("%d",&sa[i][j]);
                }
            }
            //getchar();
            for(i=1;i<=52;i++)card[i]=i-1;
            //while(gets(num))
            while(scanf("%d",&tmp)!=EOF)
            {
                //tmp=Getdig(num);
                if(tmp==0)break;
                for(i=1;i<=52;i++)
                {
                    int a=sa[tmp][i];
                    _card[i]=card[a];
                }
                for(i=1;i<=52;i++)
                    card[i]=_card[i];
                for(i=1;i<=52;i++)
                {
                    int d=card[i]%13;
                    int c=card[i]/13;
                    printf("%s of %s
    ",val[d],suit[c]);
                }
                printf("
    ");
            }
        }
    }
    /*
    
    */
    View Code

     6、110206/10044 Erdos Numbers 

    此题很纠结,一开始没有读清题意,此题可以简化为图模型,求最短路径

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<ctype.h>
    using namespace std;
    const int Max=100005;
    char pap[Max];
    char name[Max][100];
    int cur=1;
    int h[Max];
    int arc[Max];
    int nxt[Max];
    int tmp[Max];
    int dis[Max];
    int q[Max];
    int tot=0;
    void search(int hp,int cn)
    {
        int i,j;
        for(i=h[hp];i!=-1;i=nxt[i])
        {
            if(arc[i]==cn)return;
        } 
        arc[tot]=cn;
        nxt[tot]=h[hp];
        h[hp]=tot;
        tot++;
    }
    void fun()
    {
        int i,j,len=strlen(pap),m=0;
        for(i=0;i<len;i++)
        {
            bool sym=false;
            if(i==0||(pap[i]!=' '&&pap[i-1]==' '))
            {
                j=0;
                while(!sym||(pap[i]!=','&&pap[i]!=':'))
                {
                    if(pap[i]==',')sym=true;
                    name[cur][j++]=pap[i++];
                }
                name[cur][j]='';
                int d=-1;
                for(j=0;j<cur;j++)
                {
                    if(strcmp(name[j],name[cur])==0)
                    {
                        d=j;
                        break;
                    }
                }
                if(d==-1)
                {
                    d=cur;
                    cur++;
                }
                tmp[m++]=d;
            }
            if(pap[i]==':')break;
        }
        for(i=0;i<m;i++)
        {
            int hp=tmp[i];
            for(j=0;j<m;j++)
            {
                if(i==j)continue;
                search(hp,tmp[j]);
            }
        }
    }
    void BFS()
    {
        int front=0,rear=1,i;
        dis[0]=0;
        while(front<rear)
        {
            int u=q[front];
            front++;
            for(i=h[u];i!=-1;i=nxt[i])
            {
                int ad=arc[i];
                if(dis[ad]==-1)
                {
                    dis[ad]=dis[u]+1;
                    q[rear++]=ad;
                }
            }
        }
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        int S=1,P,N,i,j;
        strcpy(name[0],"Erdos, P.");
        while(T--)
        {
            cur=1;
            tot=0;
            q[0]=0;
            memset(h,-1,sizeof(h));
            memset(nxt,-1,sizeof(nxt));
            memset(dis,-1,sizeof(dis));
            scanf("%d%d",&P,&N);
            getchar();
            for(i=0;i<P;i++)
            {
                gets(pap);
                fun();
            }
            BFS();
            printf("Scenario %d
    ",S++);
            for(i=0;i<N;i++)
            {
                gets(pap);
                printf("%s ",pap);
                for(j=0;j<cur;j++)
                {
                    if(strcmp(name[j],pap)==0)
                    {                    
                        if(dis[j]!=-1)printf("%d
    ",dis[j]);
                        else printf("infinity
    ");
                        break;
                    }
                }
                if(j>=cur)printf("infinity
    ");
            }
        }
        return 0;
    }
    /*
    10
    8  5
    Smith, M.N., Martin, G., Erdos, P.: Newtonian forms of prime factor matrices 
    Erdos, P., Zeisig, W.: Stuttering in petri nets
    Smith, M.N., Chen, X.: First oder derivates in structured programming
    Jablonski, T., Hsueh, Z.: Selfstabilizing data structures
    Mith, M.N., Xth, M.N.: Selfstabilizing data structures
    fdhgfgh, T., Smith, M.N.: Selfstabilizing data structures
    Mith, M.N.:Selfstabilizing data structures
    Zeisig, W., Hsueh, Z.: Selfstabilizing data structures
    Smith, M.N.
    Hsueh, Z.
    Chen, X.
    Mith, M.N.
    Xth, M.N.
    
    8  5
    Smith, M.N., Martin, G.,: Newtonian forms of prime factor matrices 
    Zeisig, W.: Stuttering in petri nets
    Smith, M.N., Chen, X.: First oder derivates in structured programming
    Jablonski, T., Hsueh, Z.: Selfstabilizing data structures
    Mith, M.N., Xth, M.N.: Selfstabilizing data structures
    fdhgfgh, T., Smith, M.N.: Selfstabilizing data structures
    Mith, M.N.:Selfstabilizing data structures
    Zeisig, W., Hsueh, Z.: Selfstabilizing data structures
    Smith, M.N.
    Hsueh, Z.
    Chen, X.
    Mith, M.N.
    Xth, M.N.
    */
    View Code

     7、110207/10258 Contest Scoreboard (比赛计分板)

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<ctype.h>
    int sub[105][15];
    int pro[105][15];
    int time[105][15];
    int vis[105];
    int con[105];
    using namespace std;
    char lin[100];
    void calc(char lin[])
    {
        int len=strlen(lin),i;
        int c,p,t;
        char sta;
        int tmp[10],m=0;
        for(i=0;i<len;i++)
        {
            tmp[m]=0;
            if(i==0||(lin[i]!=' '&&lin[i-1]==' '))
            {
                while(i<len&&lin[i]!=' ')
                {
                    if(isdigit(lin[i]))
                        tmp[m]=tmp[m]*10+lin[i++]-'0';
                    else
                        sta=lin[i++];            
                }
                if(isdigit(lin[i-1]))
                {
                    if(m==0)
                        c=tmp[m];
                    if(m==1)
                        p=tmp[m];
                    else
                        t=tmp[m];
                    m++;
                }
            }
        }
        vis[c]=1;
        if(sta=='C'&&pro[c][p]==0)
        {
            pro[c][p]=1;
            time[c][p]=t+20*sub[c][p];
            time[c][10]+=time[c][p];
            pro[c][10]++;
        }
        else if(sta=='I'&&pro[c][p]==0)
        {
            sub[c][p]++;
        }
    }
    bool cmp(int a,int b)
    {
        if(vis[a]>vis[b])
            return 1;
        else if(vis[a]==vis[b])
        {
            if(pro[a][10]>pro[b][10])return 1;
            else if(pro[a][10]==pro[b][10])
            {
                if(time[a][10]<time[b][10])return 1;
                else if(time[a][10]==time[b][10])
                {
                    return a<b;
                }
                return 0;
            }
            return 0;    
        }
        return 0;
    
    }
    int main()
    {
        int T,i;
        scanf("%d",&T);
        getchar();
        gets(lin);
        while(T--)
        {
            memset(sub,0,sizeof(sub));
            memset(pro,0,sizeof(pro));
            memset(time,0,sizeof(time));
            memset(vis,0,sizeof(vis));
            for(i=1;i<=100;i++)con[i]=i;
            while(gets(lin)!=NULL)
            {
                int len=strlen(lin);
                if(len==0)break;
                calc(lin);
            }
            sort(con+1,con+101,cmp);
            for(i=1;i<=100;i++)
            {
                if(vis[con[i]]!=1)break;
                printf("%d %d %d
    ",con[i],pro[con[i]][10],time[con[i]][10]);
            }
            if(T)printf("
    ");
        }
        return 0;
    }
    /*
    3
    
    1 2 10 I
    3 1 11 C
    1 2 19 R
    1 2 21 C
    1 1 25 C
    
    2 2 10 I
    3 1 11 C
    1 2 19 R
    1 2 21 C
    1 1 25 C
    */
    View Code

     8、(hdu)1074  Doing homework

    用到了动态规划的思想

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<ctype.h>
    using namespace std;
    const int Max=1<<16;
    const int INF=1000000000;
    typedef __int64 lld ;
    int h[20];
    int dp[Max];
    int day[Max];
    lld ord[Max];
    int dead[20],cost[20];
    int node[Max];
    int nxt[Max];
    char name[20][100];
    int tot;
    void GetArr(int s,int cnt,int len,int res)
    {
        if(len<cnt)return ;
        if(cnt==0)
        {
            node[tot]=res<<len;
            nxt[tot]=h[s];
            h[s]=tot;
            tot++;
            return;
        }
        GetArr(s,cnt-1,len-1,(res<<1)+1);
        GetArr(s,cnt,len-1,res<<1);
    }
    void PritC(lld cnt,int t)
    {
        if(t<=0)return;
        PritC(cnt/16,--t);
        printf("%s
    ",name[cnt%16]);
    }
    int main()
    {
        memset(nxt,-1,sizeof(nxt));
        memset(h,-1,sizeof(h));
        int i,j,T,C,k;
        for(i=1;i<=15;i++)
        {
            GetArr(i,i,15,0);
        }
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&C);
            for(i=0;i<(1<<C);i++)dp[i]=-INF;
            memset(day,0,sizeof(day));
            memset(ord,-1,sizeof(ord));
            int mx=1<<C;
            for(i=0;i<C;i++)
            {
                scanf("%s%d%d",name[i],&dead[i],&cost[i]);
                dp[1<<i]=dead[i]>cost[i]?0:dead[i]-cost[i];
                day[1<<i]=cost[i];
                ord[1<<i]=i;
            }
            for(i=1;i<C;i++)
            {
                for(k=h[i];k!=-1;k=nxt[k])
                {
                    int t=node[k];
                    if(t>=mx)continue;
                    for(j=0;j<C;j++)
                    {
                        int tmp=1<<j;
                        if((tmp&t)!=0)continue;
                        int cnt=tmp|t;
                        if(dp[cnt]==-INF)day[cnt]=day[t]+cost[j];
                        int del=dead[j]-cost[j]-day[t];
                        if(del>0)del=0;
                        int cur=dp[t]+del;
                        lld rd=ord[t]*16+j;
                        if(dp[cnt]<cur)
                        {
                            dp[cnt]=cur;
                            ord[cnt]=rd;
                        }
                        else if(dp[cnt]==cur&&ord[cnt]>rd)
                        {
                            ord[cnt]=rd;
                        }
                    }
                }
            }
            //for(i=1;i<(1<<C);i++)printf("dp[%d]=%d,day[%d]=%d,ord[%d]=%d
    ",i,dp[i],i,day[i],i,ord[i]);
            //printf("ord=%I64d
    ",ord[(1<<C)-1]);
            printf("%d
    ",-dp[(1<<C)-1]);
            PritC(ord[(1<<C)-1],C);
        }
        return 0;
    }
    /*
    100
    1
    English 1 20
    2
    Computer 3 3
    English 3 3
    3
    Computer 3 3
    English 20 1
    Math 3 2
    6
    A 3 3
    B 3 3
    C 20 1
    D 6 3
    E 3 2
    F 6 3
    12
    A 3 3
    B 3 3
    C 20 1
    D 6 3
    E 3 2
    F 6 3
    H 3 3
    I 3 3
    J 20 1
    K 6 3
    L 3 2
    M 6 3
    10
    A 3 3
    B 3 3
    C 20 1
    D 6 3
    E 3 2
    F 6 3
    H 3 3
    I 3 3
    J 20 1
    K 6 3
    8
    A 3 3
    B 3 3
    C 20 1
    D 6 3
    E 3 2
    F 6 3
    H 3 3
    I 3 3
    */
    View Code

     9、110208/10149 Yahtzee (Yahtzee 游戏)

    同上一题,使用了状态压缩动态规划

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<ctype.h>
    using namespace std;
    int dice[10];
    int sco[20][20];
    const int Max=1<<13;
    int dp[20][Max][65];
    int route[20][Max][65];
    int h[20];
    int tot=0;
    int node[Max],nxt[Max];
    void fun(int s,int cnt,int len,int res)
    {
        if(cnt>len)return;
        if(cnt==0)
        {
            node[tot]=res<<len;
            nxt[tot]=h[s];
            h[s]=tot;
            tot++;
            return;
        }
        fun(s,cnt-1,len-1,(res<<1)+1);
        fun(s,cnt,len-1,(res<<1));
    }
    bool cmp(int a,int b)
    {
        return a<b;
    }
    int calc(int cnt)
    {
        int i,sum=0;
        for(i=0;i<5;i++)
        {
            if(dice[i]==cnt)sum+=cnt;
        }
        return sum;
    }
    int sk()
    {
        int i,cnt=1,max=1;
        for(i=1;i<=5;i++)
        {
            if(i<5&&dice[i]==dice[i-1])cnt++;
            else
            {
                if(cnt>max)max=cnt;
                cnt=1;
            }
        }
        return max;
    }
    int sl()
    {
        int i,cnt=1,max=1;
        for(i=1;i<=5;i++)
        {
            if(i<5&&dice[i]-dice[i-1]==1)cnt++;
            else
            {
                if(max<cnt)max=cnt;
                cnt=1;
            } 
        }
        return max;
    }
    int sf()
    {
        int i,cnt=1,max=1,min=5;
        for(i=1;i<=5;i++)
        {
            if(i<5&&dice[i]==dice[i-1])cnt++;
            else
            {
                if(cnt>max)max=cnt;
                if(cnt<min)min=cnt;
                cnt=1;
            }
        }
        if(max==3&&min==2)return 1;
        return 0;
    }
    int gp(int tmp)
    {
        int cnt=0;
        while(tmp)
        {
            cnt++;
            tmp=tmp>>1;
        }
        return cnt;
    }
    void DP()
    {
        int i,j,k,tmp,t,c,m,s,sum,end=0; 
        for(i=0;i<13;i++)
        {
            k=0;
            if(i<6)k=sco[1][i];
            dp[1][1<<i][k]=sco[1][i];
        }
        for(i=1;i<13;i++)
        {
            for(j=h[i];j!=-1;j=nxt[j])
            {
                tmp=node[j];
                for(k=0;k<13;k++)
                {
                    t=1<<k;
                    if((tmp&t)!=0)continue;
                    c=tmp|t;
                    for(m=0;m<=63;m++)
                    {
                        if(dp[i][tmp][m]==0)continue;
                        sum=dp[i][tmp][m]+sco[i+1][k];
                        s=m;
                        if(k<6)s+=sco[i+1][k];
                        if(s>63)s=63;
                        if(dp[i+1][c][s]<sum)
                        {
                            dp[i+1][c][s]=sum;
                            route[i+1][c][s]=tmp*100+m;
                        }
                    }
                }
            }
        }
        c=(1<<13)-1;
        m=-1;
        for(i=0;i<63;i++)
        {
            //printf("%d-%d
    ",i,dp[13][c][i]);
            if(dp[13][c][i]>m)
            {
                m=dp[13][c][i];
                end=i;
            }
        }
        int bon=0;
        if(m<(dp[13][c][63]+35))
        {
            m=dp[13][c][63]+35;
            end=63;
            bon=35;
        }
        int w[20],x=13,res[20];
        while(x>1)
        {
            w[x]=gp((route[x][c][end]/100)^c);
            if(x==2)
            {
                w[x-1]=gp(route[x][c][end]/100);
            }
            int t=c;
            c=route[x][t][end]/100;
            end=route[x][t][end]%100;
            x--;
        }
        for(i=1;i<=13;i++)res[w[i]]=sco[i][w[i]-1];
        for(i=1;i<=13;i++)printf("%d ",res[i]);
        printf("%d %d
    ",bon,m);
    }
    int main()
    {
        int t=1,i,j,sum;
        memset(sco,0,sizeof(sco));
        memset(h,-1,sizeof(h));
        memset(nxt,-1,sizeof(nxt));
        for(i=1;i<=13;i++)
        {
            fun(i,i,13,0);
        }
        while(scanf("%d",&dice[0])!=EOF)
        {
            sum=dice[0];
            for(i=1;i<5;i++)
            {
                scanf("%d",&dice[i]);
                sum+=dice[i];
            }
            sort(dice,dice+5,cmp);
            for (j=0;j<6;j++)sco[t][j]=calc(j+1);
            sco[t][j]=sum; 
            int cnt=sk();
            if(cnt>=3)sco[t][7]=sum;
            if(cnt>=4)sco[t][8]=sum;
            if(cnt==5)sco[t][9]=50;
            cnt=sl();
            if(cnt>=4)sco[t][10]=25;
            if(cnt==5)sco[t][11]=35;
            if(sf())sco[t][12]=40;
            t++;
            if(t>13)
            {    
                memset(dp,0,sizeof(dp));
                memset(route,0,sizeof(route));
                DP();
                memset(sco,0,sizeof(sco));
                t=1;
            }
        }
        return 0;
    }
    View Code

     10、(poj)1321棋盘问题

    同使用状态压缩

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<ctype.h>
    using namespace std;
    char bord[10][10];
    int dp[1<<10];
    int tdp[1<<10];
    int xdp[1<<10];
    int calc(int x,int k)
    {
        int cnt=0;
        while(x)
        {
            cnt+=x&1;
            x>>=1;
        }
        return cnt==k;
    }
    
    int main()
    {
        int n,k,i,j,t;
        while(scanf("%d%d",&n,&k)!=EOF)
        {
            if(n==-1&&k==-1)break;
            getchar();
            int max=1<<n;
            memset(dp,0,sizeof(dp));
            memset(xdp,0,sizeof(xdp));
            for(i=1;i<=n;i++)
            {
                gets(bord[i]);
            }
            for(i=1;i<=n;i++)
            {
                for(j=0;j<n;j++)
                {
                    if(bord[i][j]=='#')
                    {
                        for(t=0;t<max;t++)tdp[t]=xdp[t];
                        for(t=0;t<max;t++)
                        {
                            int tmp=1<<j;
                            if(t==0)
                            {
                                tdp[tmp]++;
                                continue;
                            }
                            if((t&tmp)!=0)continue;
                            tdp[t|tmp]+=tdp[t];
                        }
                        for(t=0;t<max;t++)dp[t]+=tdp[t]-xdp[t];
                    }
                }
                for(j=0;j<max;j++)xdp[j]=dp[j];
            }
            int cnt=0;
            for(i=0;i<max;i++)
            {
                if(calc(i,k))
                {
                    cnt+=dp[i];
                }
            }
            printf("%d
    ",cnt);
        }
        return 0;
    }
    /*
    4 4
    #..#
    ..#.
    .#..
    #..#
    
    4 4
    #..#
    #.#.
    .#..
    #..#
    */
    View Code
  • 相关阅读:
    mysqlsql练习题
    日志打印
    【JVM】落日黄昏后:CMS垃圾回收器
    【JVM】调优常用参数总结
    【JVM】如何选择垃圾回收器?
    【Spring Boot】thymeleaf模板引擎的使用
    printf
    CSV文件——逗号分隔值(字符分隔值)
    VectorCAST的基本操作步骤
    VectorCAST常见操作byWXT
  • 原文地址:https://www.cnblogs.com/varcom/p/4050206.html
Copyright © 2020-2023  润新知