zoukankan      html  css  js  c++  java
  • 2014 ACM/ICPC Asia Regional Xi'an Online

    A Post Robot

    。。。嗯,比赛时手拍了一个自动机,注意是手拍。。= =

     1 /*
     2 ID:esxgx1
     3 LANG:C++
     4 PROG:A
     5 */
     6 #include <cstdio>
     7 #include <cstring>
     8 #include <iostream>
     9 #include <algorithm>
    10 using namespace std;
    11 
    12 char str[10007];
    13 
    14 int main(void)
    15 {
    16     #ifndef ONLINE_JUDGE
    17     freopen("in.txt", "r", stdin);
    18     #endif
    19     while(gets(str) != NULL) {
    20         int dd = 0;
    21         for(int i = 0; str[i]; ++i) {
    22 _failed:
    23             //printf("%c %d
    ", str[i], dd);
    24             if (dd == 0) {
    25                 if (str[i] == 'A') dd = 1;
    26                 else if (str[i] == 'i') dd = 5;
    27                 else if (str[i] == 'S') dd = 11;
    28             }
    29             else if (dd == 1) {
    30                     if (str[i] == 'p') dd = 2;
    31                     else {dd = 0; goto _failed;}
    32             }
    33             else if (dd == 2) {
    34                     if (str[i] == 'p') dd = 3;
    35                     else {dd = 0; goto _failed;}
    36             }
    37             else if (dd == 3) {
    38                     if (str[i] == 'l') dd = 4;
    39                     else {dd = 0; goto _failed;}
    40             }
    41             else if (dd == 4) {
    42                     dd = 0;
    43                     if (str[i] == 'e') printf("MAI MAI MAI!
    ");
    44                     else {dd = 0; goto _failed;}
    45             }
    46             else if (dd == 5) {
    47                 if (str[i] == 'P') dd = 6;
    48                 else {dd = 0; goto _failed;}
    49             }
    50             else if (dd == 6) {
    51                 if (str[i] == 'h') dd = 7;
    52                 else if (str[i] == 'a') dd = 10;
    53                 else if (str[i] == 'o') dd = 10;
    54                 else {dd = 0; goto _failed;}
    55             }
    56             else if (dd == 7) {
    57                 if (str[i] == 'o') dd = 8;
    58                 else {dd = 0; goto _failed;}
    59             }
    60             else if (dd == 8) {
    61                 if (str[i] == 'n') dd = 9;
    62                 else {dd = 0; goto _failed;}
    63             }
    64             else if (dd == 9) {
    65                 dd = 0;
    66                 if (str[i] == 'e') printf("MAI MAI MAI!
    ");
    67                 else {dd = 0; goto _failed;}
    68             }
    69             else if (dd == 10) {
    70                 dd = 0;
    71                 if (str[i] == 'd') printf("MAI MAI MAI!
    ");
    72                 else {dd = 0; goto _failed;}
    73             }else if (dd == 11) {
    74                 if (str[i] == 'o') dd = 12;
    75                 else {dd = 0; goto _failed;}
    76             } else if (dd == 12) {
    77                 if (str[i] == 'n') dd = 13;
    78                 else {dd = 0; goto _failed;}
    79             } else if (dd == 13) {
    80                 dd = 0;
    81                 if (str[i] == 'y') printf("SONY DAFA IS GOOD!
    ");
    82                 else {dd = 0; goto _failed;}
    83             }
    84         }
    85     }
    86     return 0;
    87 }

    C Paint Pearls

    状态方程好想,但预处理真的不是很容易。简单来说预处理用到了一个单调性,即颜色不同的越多越要往回看。

    具体分析干脆引用某大神的:

    状态转移方程很好想,dp[i] = min(dp[j]+o[j~i]^2,dp[i]) ,o[j~i]表示从j到i颜色的种数。
    普通的O(n*n)是会超时的,可以想到o[]最大为sqrt(n),问题是怎么快速找到从i开始往前2种颜色、三种、四种。。。o[]种的位置。
    离散化之后,可以边走边记录某个数最后一个出现的位置,初始为-1,而所要求的位置就等于
    if(last[a[i]]==-1) 该数没有出现过,num[i][1] = i,num[i][j+1] = num[i-1][j];
    else  last[a[i]]之前 num[i][1] = i,num[i][j+1] = num[i-1][j],之后num[i][j]= num[i-1][j];

    当然赛时我这个渣渣是肯定写不出来的,后来看了这个分析写了一份代码,个人感觉按这个思路真的不是很好写(也许应该看看thu的那份):

    /*
    ID:esxgx1
    LANG:C++
    PROG:xian_C
    */
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    #define NN        500007
    
    int coloridx[NN], color[NN], ncolors;
    
    int cpre[NN];                // 某个颜色上一次出现的位置
    int clbck[NN];                // n颜色回溯
    
    int _dp[NN+1], *dp = &_dp[1];
    
    int main(void)
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
        #endif
    
        int N;
        while(scanf("%d", &N) > 0) {
            for(int i=0; i<N; ++i) {
                scanf("%d", &color[i]);
                coloridx[i] = color[i];
            }
            // 颜色离散化
            sort(color, color + N);
            ncolors = unique(color, color + N) - color;
    
            for(int i=0; i<N; ++i)
                coloridx[i] = lower_bound(color, color + ncolors, coloridx[i]) - color;
    
    
            memset(clbck, -1, sizeof(clbck));
            memset(cpre, -1, sizeof(cpre));
    
            clbck[1] = cpre[coloridx[0]] = 0;
            dp[0] = 1;
    
            for(int i=1; i<N; ++i) {
                dp[i] = 0x3f3f3f3f;
                if (cpre[coloridx[i]] != i-1) {
                    if (cpre[coloridx[i]] < 0)    {    // 颜色没出现过
                        for(int j = sqrt(N); j>0; --j) clbck[j+1] = clbck[j];
                    } else {
                        int j = sqrt(N) + 1;
                        for(; j > 0 && (clbck[j] < 0 || clbck[j] <= cpre[coloridx[i]]); --j);
                        for(--j; j > 0 && clbck[j] > cpre[coloridx[i]]; --j) clbck[j+1] = clbck[j];
                    }
                    clbck[1] = i;
                }
                for(int j = 1; clbck[j] >= 0; ++j) {
                    dp[i] = min(dp[i], dp[clbck[j]-1] + j*j);
                    //printf("(%d) j=%d %d [pre%d]
    ", i+1, j, clbck[j]+1, cpre[coloridx[i]] + 1);
                }
    
                //printf("%d %d
    ", i, dp[i]);
                cpre[coloridx[i]] = i;
            }
            printf("%d
    ", dp[N-1]);
    
        }
        return 0;
    }

    E Game

    真的很凑巧,这题是我们的省赛原题,然后又yy了一份代码。。

    #include <cstdio>
    using namespace std;
     
    int N;
     
    int main()
    {
        while(scanf("%d", &N) > 0) {
            int i, j;
            j = 0;
            for(i=0; i<N; ++i) {
                int k;
                scanf("%d", &k);
                j ^= k;
            }
            printf(j? "Win
    " : "Lose
    ");
        }
        return 0;
    }

     F Dice

    这题我没参与,不知道讲了神马。。听队友说是BFS判重,贴一下我们队的代码。。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<queue>
     5 using namespace std;
     6 int hash[700000];
     7 int dis[700000];
     8 struct dice1{
     9     int top,but,lef,rig,fro,bac;
    10 };
    11 int enc(int a,int b,int c,int d,int e,int f){
    12     return a*100000+b*10000+c*1000+d*100+e*10+f;
    13 }
    14 int enc(dice1 tmp){
    15     return tmp.top*100000+tmp.but*10000+tmp.lef*1000+tmp.rig*100+tmp.fro*10+tmp.bac;
    16 }
    17 dice1 dice;
    18 dice1 rol(dice1 tmp){
    19     dice1 ret;
    20     ret.top=tmp.rig;
    21     ret.rig=tmp.but;
    22     ret.but=tmp.lef;
    23     ret.lef=tmp.top;
    24     ret.fro=tmp.fro;
    25     ret.bac=tmp.bac;
    26     return ret;
    27 }
    28 dice1 ror(dice1 tmp){
    29     dice1 ret;
    30     ret.top=tmp.lef;
    31     ret.rig=tmp.top;
    32     ret.but=tmp.rig;
    33     ret.lef=tmp.but;
    34     ret.fro=tmp.fro;
    35     ret.bac=tmp.bac;
    36     return ret;
    37 }
    38 dice1 rof(dice1 tmp){
    39     dice1 ret;
    40     ret.top=tmp.bac;
    41     ret.fro=tmp.top;
    42     ret.but=tmp.fro;
    43     ret.bac=tmp.but;
    44     ret.lef=tmp.lef;
    45     ret.rig=tmp.rig;    
    46     return ret;
    47 }
    48 dice1 rob(dice1 tmp){
    49     dice1 ret;
    50     ret.top=tmp.fro;
    51     ret.fro=tmp.but;
    52     ret.but=tmp.bac;
    53     ret.bac=tmp.top;
    54     ret.lef=tmp.lef;
    55     ret.rig=tmp.rig;
    56     return ret;
    57 }
    58 int main(){
    59     int a[7],b[7];
    60     while(scanf("%d%d%d%d%d%d",&a[1],&a[2],&a[3],&a[4],&a[5],&a[6])>0){
    61         memset(hash,0,sizeof(hash));
    62         memset(dis,0,sizeof(dis));
    63         scanf("%d%d%d%d%d%d",&b[1],&b[2],&b[3],&b[4],&b[5],&b[6]);
    64         hash[enc(b[1],b[2],b[3],b[4],b[5],b[6])]=2;
    65         queue<dice1> q;
    66         dice1 aaa;
    67         aaa.top=a[1];
    68         aaa.but=a[2];
    69         aaa.lef=a[3];
    70         aaa.rig=a[4];
    71         aaa.fro=a[5];
    72         aaa.bac=a[6];
    73         q.push(aaa);
    74         dis[enc(q.front())]=0;
    75         int ans=-1;
    76         while(!q.empty()){
    77             dice1 tmp=q.front();q.pop();
    78             if(hash[enc(tmp)]==2){
    79                 ans=dis[enc(tmp)];
    80                 break;
    81             }
    82             if(dis[enc(tmp)]>4){
    83                 ans=-1;break;
    84             }
    85             if(hash[enc(tmp)]!=1){
    86                 dis[enc(rol(tmp))]=dis[enc(tmp)]+1;
    87                 q.push(rol(tmp));
    88                 dis[enc(ror(tmp))]=dis[enc(tmp)]+1;
    89                 q.push(ror(tmp));
    90                 dis[enc(rof(tmp))]=dis[enc(tmp)]+1;
    91                 q.push(rof(tmp));
    92                 dis[enc(rob(tmp))]=dis[enc(tmp)]+1;
    93                 q.push(rob(tmp));
    94             }
    95         }
    96         printf("%d
    ",ans);
    97     }
    98     return 0;
    99 }

    H Number Sequence

    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    int n;
    long long ans[100007];
    
    int a[100007];
    
    int main()
    {
          int i;
          long long x,sum;
          while (scanf("%d",&n) > 0) {
                 for(int i=0; i<=n; ++i)
                    scanf("%d", &a[i]);
                 x = 1;
                 while (x<=n) x <<= 1;
                 x--;
                 memset(ans,-1,sizeof(ans));
    
                 for (i=n; i>=0; --i) {
                       if (ans[i]!=-1) continue;
                       while ((x^i)>n || ans[x^i]!=-1) x>>=1;
                       ans[x^i]=i,ans[i]=x^i;
                 }
                 sum=0;
                 for (i=0; i<=n; ++i)
                       sum+=i^ans[i];
                 printf("%I64d
    ",sum);
                 for (i=0;i<=n;i++) {
                    if (i) putchar(' ');
                    printf("%I64d",ans[a[i]]);
                 }
                 putchar('
    ');
          }
          return 0;
    }

    I 233 Matrix

    快速幂,神队友脑洞大开yy了这个矩阵,然后就没有然后了。。

     1 /*
     2 ID:esxgx1
     3 LANG:C++
     4 PROG:I
     5 */
     6 #include <cstdio>
     7 #include <cstring>
     8 #include <iostream>
     9 #include <algorithm>
    10 using namespace std;
    11 
    12 
    13 #define MM 17
    14 
    15 struct matrix {
    16     long long m[MM][MM];
    17 };
    18 
    19 #define MOD        10000007
    20 
    21 int Nn;
    22 
    23 struct matrix m_mult(const struct matrix &a, const struct matrix &b)
    24 {
    25     struct matrix r;
    26     for(int i=0; i<Nn; ++i) {
    27         for(int j=0; j<Nn; ++j) {
    28             r.m[i][j] = 0;
    29             for(int k = 0; k < Nn; ++k) {
    30                 r.m[i][j] += a.m[i][k] * b.m[k][j];
    31                 r.m[i][j] %= MOD;
    32             }
    33         }
    34     }
    35     return r;
    36 }
    37 
    38 struct matrix m_pow(struct matrix a, int n)
    39 {
    40     struct matrix p;
    41     memset(&p, 0, sizeof(p));
    42     for(int i=0; i<Nn; ++i)
    43         p.m[i][i] = 1;
    44     while(n) {
    45         if (n & 1) p = m_mult(p, a);
    46         a = m_mult(a, a);
    47         n >>= 1;
    48     }
    49     return p;
    50 }
    51 
    52 int main(void)
    53 {
    54     #ifndef ONLINE_JUDGE
    55     freopen("in.txt", "r", stdin);
    56     #endif
    57 
    58     int N, M;
    59     while(scanf("%d%d", &N, &M) > 0) {
    60         ++N;
    61         matrix p;
    62         memset(&p, 0, sizeof(p));
    63         for(int i=0; i < N; ++i) {
    64             p.m[i][0] = 10;
    65             for(int j=1; j<=i; ++j)
    66                 p.m[i][j] = 1;
    67             p.m[i][N] = 1;
    68         }
    69         p.m[N][N] = 1, Nn = N+1;
    70         p = m_pow(p, M);
    71 
    72         matrix q;
    73         memset(&q, 0, sizeof(q));
    74         q.m[0][0] = 23, q.m[N][0] = 3;
    75         for(int i=1; i<N; ++i)
    76             scanf("%I64d", &q.m[i][0]);
    77         p = m_mult(p, q);
    78         //p = q;
    79         printf("%d
    ", p.m[N-1][0]);
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    数据类型转换:高级向低级转换可能出现的问题和取得不同精度的方法
    Xen Server虚拟机数据恢复的方法和数据恢复过程
    VMware虚拟机误删除vmdk文件后如何恢复?
    MSSQL 2000 错误823恢复
    服务器存储误操作导致数据丢失的恢复过程
    我从业11年来遇到的最奇葩的raid0+1数据恢复经历
    Raid 5数据恢复原理以及raid 5数据恢复实际操作案例
    服务器数据恢复_Linux网站服务器故障数据恢复案例
    Raid5两块硬盘掉线可以恢复数据吗_raid数据恢复案例分享
    V7000存储数据恢复_底层结构原理拆解及Mdisk磁盘掉线数据恢复方法
  • 原文地址:https://www.cnblogs.com/e0e1e/p/icpc2014_xian.html
Copyright © 2011-2022 走看看