zoukankan      html  css  js  c++  java
  • 2014 ACM/ICPC Asia Regional Xi'an Online(HDU 5007 ~ HDU 5017)

    题目链接

    A题 :(字符串查找,水题)

    题意 :输入字符串,如果字符串中包含“ Apple”, “iPhone”, “iPod”, “iPad” 就输出 “MAI MAI MAI!”,如果出现 “Sony” 就输出“SONY DAFA IS GOOD!” ,大小写敏感。

    思路 : 字符串查找,水题。

     1 #include <string.h>
     2 #include <stdio.h>
     3 #include <iostream>
     4 
     5 using namespace std ;
     6 
     7 char str[20000];
     8 
     9 int main()
    10 {
    11     int i;
    12     while(gets(str))
    13     {
    14         int len=strlen(str);
    15         for(i=0; i<len; i++)
    16         {
    17             if(str[i]=='A' && str[i+1]=='p' && str[i+2]=='p' && str[i+3]=='l' && str[i+4]=='e')
    18                 printf("MAI MAI MAI!
    ");
    19             if(str[i]=='i' && str[i+1]=='P' && str[i+2]=='h' && str[i+3]=='o' && str[i+4]=='n'&&str[i+5] == 'e')
    20                 printf("MAI MAI MAI!
    ");
    21             if(str[i]=='i' && str[i+1]=='P' && str[i+2]=='a' && str[i+3]=='d')
    22                 printf("MAI MAI MAI!
    ");
    23             if(str[i]=='i' && str[i+1]=='P' && str[i+2]=='o' && str[i+3]=='d')
    24                 printf("MAI MAI MAI!
    ");
    25             if(str[i]=='S' && str[i+1]=='o' && str[i+2]=='n' && str[i+3]=='y')
    26                 printf("SONY DAFA IS GOOD!
    ");
    27         }
    28     }
    29     return 0;
    30 }
    View Code

    E题 :(博弈)

    题意 : n堆珠子,两个人轮流玩儿,每一次,玩家从某一堆中拿出一些扔掉,至少拿出一个,然后对这堆剩下的,玩家可以不再操作,或者可以将剩下的分为两堆,但是每堆至少一个,然后下一个玩家玩儿,如果哪个玩家玩完一把之后没有珠子了。谁就胜了。

    思路 : 类似于Nim游戏,就是多了一个分堆的问题,其实无大碍。。。还是那样分。。。。

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    
    using namespace std ;
    
    int main()
    {
        int n ;
        while(scanf("%d",&n)!=EOF)
        {
            int a,sum = 0 ;
            for(int i = 0 ; i < n ;i++)
            {
                scanf("%d",&a) ;
                sum ^= a ;
            }
            if(sum)puts("Win") ;
            else puts("Lose") ;
        }
        return 0 ;
    }
    View Code

    F题 :(BFS) 

    题意 : 告诉你一个骰子上下左右前后上的数字分别是多少,问转最少多少次能够转到另一个骰子的状态,如果不能输出-1,有前转后转左转右转。

    思路 : 记录下当前状态在四种转向方式之后变成什么状态,然后加入队列,看能否转到终态。

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <queue>
    
    using namespace std ;
    
    int mul[7] = {1,10,100,1000,10000,100000};
    struct node
    {
        int sta,step ;
        friend bool operator < (node a,node b)
        {
            return a.step > b.step ;
        }
    } p,temp1,temp2;
    int state,a[7] ;
    bool vis[700000] ;
    
    int BFS()
    {
        priority_queue<node>Q ;
        Q.push(p) ;
        vis[p.sta] = true ;
        while(!Q.empty())
        {
            temp1 = Q.top() ;
            Q.pop() ;
            if(temp1.sta == state) return temp1.step ;
            int ss = temp1.sta ;
            for(int i = 0 ; i < 6 ; i++)
            {
                a[i] = ss % 10 ;
                ss /= 10 ;
            }
            //左转
            p.sta = 0 ;
            p.step = temp1.step + 1 ;
            p.sta = 1*a[3]+10*a[2]+100*a[0]+1000*a[1]+10000*a[4]+100000*a[5] ;
            if(!vis[p.sta])
            {
                Q.push(p) ;
                vis[p.sta] = true ;
            }
            //右转
            p.sta = 0 ;
            p.step = temp1.step + 1 ;
            p.sta = 1*a[2]+10*a[3]+100*a[1]+1000*a[0]+10000*a[4]+100000*a[5] ;
            if(!vis[p.sta])
            {
                Q.push(p) ;
                vis[p.sta] = true ;
            }
            //后转
            p.sta = 0 ;
            p.step = temp1.step + 1 ;
            p.sta = 1*a[4]+10*a[5]+100*a[2]+1000*a[3]+10000*a[1]+100000*a[0] ;
            if(!vis[p.sta])
            {
                Q.push(p) ;
                vis[p.sta] = true ;
            }
            //前转
            p.sta = 0 ;
            p.step = temp1.step + 1 ;
            p.sta = 1*a[5]+10*a[4]+100*a[2]+1000*a[3]+10000*a[0]+100000*a[1] ;
            if(!vis[p.sta])
            {
                Q.push(p) ;
                vis[p.sta] = true ;
            }
        }
        return -1 ;
    }
    int main()
    {
        int a;
        while(scanf("%d",&a)!=EOF)
        {
            p.sta = a ;
            for(int i = 1 ; i < 6 ; i++)
            {
                scanf("%d",&a) ;
                p.sta += a*mul[i] ;
            }
            p.step = 0 ;
            state = 0 ;
            for(int i = 0 ; i < 6 ; i++)
            {
                scanf("%d",&a) ;
                state += a*mul[i] ;
            }
            //printf("%d %d
    ",p.sta,state) ;
            memset(vis,false,sizeof(vis)) ;
            if(p.sta == state)
            {
                puts("0") ;
                continue ;
            }
            int t = BFS() ;
            printf("%d
    ",t) ;
        }
        return 0 ;
    }
    View Code

     H题 : (位运算)

    题意 : 有n+1个数,数组a满足两个条件,是数组里的所有数大小都在[0,n]之间,而且两两不相等,b数组也满足这个条件,然后让你求t = (a0 ⊕ b0) + (a1 ⊕ b1) +···+ (an ⊕ bn)这个t的最大值,然后输出当t最大的时候b数组的数分别是什么。

    思路 : 给你一个数,你所能异或到的最大数就是全都是1,例如5(101)能够异或到的最大数就是111,是跟010异或之后,for循环倒着找每个数跟全都是1的情况下得到的数是多少即可。a^b=c,则a^c=b,b^c=a。。。。。。

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 
     5 using namespace std;
     6 
     7 int a[101011],b[101011],vis[101011];
     8 
     9 int sum(int x)//求这个数有多少位
    10 {
    11     int cnt = 0 ;
    12     while(x)
    13     {
    14         x >>= 1 ;
    15         cnt ++ ;
    16     }
    17     return cnt ;
    18 }
    19 int main()
    20 {
    21     int n ;
    22     while(scanf("%d",&n)!= EOF)
    23     {
    24         memset(vis,0,sizeof(vis)) ;
    25         for(int i = 0 ; i <= n ; i++)
    26         {
    27             scanf("%d",&a[i]) ;
    28         }
    29         for(int i = n ; i >= 0 ; i--)
    30         {
    31             if(vis[i]) continue ;
    32             int ss = (1 << sum(i)) -1 ;//求出这个数全是1
    33             int temp = ss ^ i ;
    34             b[temp] = i ;
    35             b[i] = temp ;
    36             vis[temp] = vis[i] = 1 ;
    37         }
    38         long long s = 0 ;
    39         for(int i = 0 ; i <= n ; i++)
    40             s += (long long)(b[i] ^ i) ;
    41         printf("%I64d
    ",s) ;
    42         for(int i = 0 ; i <= n ; i++)
    43             printf(i == n ? "%d
    ":"%d ",b[a[i]]) ;
    44     }
    45     return 0 ;
    46 }
    View Code

     I题:(矩阵快速幂)

    题意 : 一个矩阵,告诉你第0行是233 2333 23333 233333……然后给出第0列,让你自己构造矩阵,a[i][j]=a[i-1][j]+a[i][j-1],然后问你a[n][m]等于多少。

    思路 : 首先构造矩阵,本题中列号与行号都是从1开始。把0所在的位置换成23,假定给定的样例是:3   7   24   47   16 ,现在的第一列就应该是23 24 47 16。由此,第二列第个数233就是由10个23加1个3组成的,再根据a[i][j]=a[i-1][j]+a[i][j-1],就可以通过前一列来推出后一列了。将3作为最后一个数。

    23      233    

    24    233+24 

    47    233+24 +47

    16    233+24 +47+16 

    3         3       

    由以上可知,将第一列横置得,23  24  47  16  3,接下来可以递推下一列了

                             233  =   10*23+0*24+0*47+0*16+1*3

                       233+24  =   10*23+1*24+0*47+0*16+1*3

                 233+24 +47 =   10*23+1*24+1*47+0*16+1*3

           233+24 +47+16 =   10*23+1*24+1*47+1*16+1*3

                                3 =     0*23+0*24+0*47+0*16+1*3

    将系数画成一个矩阵  10 0 0 0 1

                               10 1 0 0 1

                               10 1 1 0 1

                               10 1 1 1 1

                                0 0 0 0 1

    所以,可以得出规律 

    a[0][m]  | 10 0 0 0 1|    | a[0][m-1] |
    a[1][m]  | 10 1 0 0 1|    | a[1][m-1] |
    a[2][m] =  | 10 1 1 0 1| *   | a[2][m-1] |
    a[3][m]  | 10 1 1 1 1|    | a[3][m-1] |
    3           | 0   0 0 0 1|     | 3              |

    所以a[n][m]就等于中间那个矩阵的m-1次方乘上第一列。。。。。。

    其他题解

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <math.h>
     4 #include <iostream>
     5 #define  LL __int64
     6 #define mod 10000007
     7 using namespace std ;
     8 int n,m ;
     9 struct mat
    10 {
    11     LL v[15][15] ;
    12     mat()
    13     {
    14         memset(v,0,sizeof(v)) ;
    15         for(int i = 1 ; i <= n+2 ; i++)
    16             v[i][i] = 1 ;
    17     }
    18 };
    19 mat e ;
    20 
    21 mat matrix_mul(mat p1,mat p2)
    22 {
    23     mat t ;
    24     for(int i = 1 ; i <= n+2 ; i++)
    25     {
    26         for(int j = 1 ; j <= n+2 ; j++)
    27         {
    28             t.v[i][j] = 0 ;
    29             for(int k = 1 ; k <= n+2 ; k++)
    30             {
    31                 t.v[i][j] = (t.v[i][j] + (p1.v[i][k]*p2.v[k][j])%mod)%mod ;
    32             }
    33         }
    34     }
    35     return t ;
    36 }
    37 mat matrix_mi(mat p,int k)
    38 {
    39     mat t ;
    40 //    for(int i = 1 ; i <= n+2 ; i ++)
    41 //        t.v[i][i] = 1 ;
    42     while(k)
    43     {
    44         if(k&1)
    45         {
    46             t = matrix_mul(t,p) ;
    47         }
    48         k >>= 1 ;
    49         p = matrix_mul(p,p) ;
    50     }
    51     return t ;
    52 }
    53 void Init()
    54 {
    55     memset(e.v,0,sizeof(e.v)) ;
    56     for(int i = 1 ; i <= n+1 ; i++)
    57         e.v[i][1] = 10 ;
    58     for(int i = 2 ; i <= n+1 ; i++)
    59     {
    60         for(int j = 2 ; j <= n+1 ; j++)
    61         {
    62             if(i >= j)
    63                 e.v[i][j] = 1 ;
    64         }
    65     }
    66     for(int i = 1 ; i <= n+2 ; i++)
    67         e.v[i][n+2] = 1 ;
    68 }
    69 int main()
    70 {
    71     LL a[1000],sum[1000] ;
    72     while(~scanf("%d %d",&n,&m))
    73     {
    74         sum[0] = 0 ;
    75         for(int i = 1 ; i <= n ; i++)
    76         {
    77             scanf("%I64d",&a[i]) ;
    78             sum[i] = sum[i-1]+a[i] ;
    79         }
    80         Init() ;
    81         mat ans = matrix_mi(e,m-1) ;
    82         mat cnt ;
    83         cnt.v[1][1] = 233 ;
    84         for(int i = 2 ; i <= n+1 ; i++)
    85             cnt.v[i][1] = (233 + sum[i-1])%mod ;
    86         cnt.v[n+2][1] = 3 ;
    87         ans = matrix_mul(ans,cnt) ;
    88         printf("%I64d
    ",ans.v[n+1][1]%mod) ;
    89     }
    90     return 0 ;
    91 }
    View Code
  • 相关阅读:
    JFreeChart生成图片
    itext生成Word
    itext生成PDF
    物理模型name与comment互相转化
    表单序列化为Json(只限input)
    c#多线程同步之EventWaitHandle的应用
    C#多线程之异步编程
    Java环境变量设置
    sharepoint 2013实践
    WPF研究之道——数据驱动UI
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/3971753.html
Copyright © 2011-2022 走看看