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\n", 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!\n"); 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!\n"); 67 else {dd = 0; goto _failed;} 68 } 69 else if (dd == 10) { 70 dd = 0; 71 if (str[i] == 'd') printf("MAI MAI MAI!\n"); 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!\n"); 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]\n", i+1, j, clbck[j]+1, cpre[coloridx[i]] + 1); } //printf("%d %d\n", i, dp[i]); cpre[coloridx[i]] = i; } printf("%d\n", 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\n" : "Lose\n"); } 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\n",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\n",sum); for (i=0;i<=n;i++) { if (i) putchar(' '); printf("%I64d",ans[a[i]]); } putchar('\n'); } 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\n", p.m[N-1][0]); 80 } 81 return 0; 82 }
This article is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
本文采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。