题意:N个Block,有四种操作可以相互移动Block使得他们叠起来。给出操作序列,求最后的状态。
Idea:模拟。
不算难,但是题意、一些细节要注意下。
#include <cstdio> #include <iostream> #include <fstream> #include <cstring> #include <string> #define OP(s) cout<<#s<<"="<<s<<" "; #define PP(s) cout<<#s<<"="<<s<<endl; using namespace std; static int s[300][300],h[300],pos[300]; void remove(int pa,int a) { int i; for (i = 1; i <= h[pa]; i++) if (s[pa][i] == a) break; for (; i < h[pa]; i++) s[pa][i] = s[pa][i+1]; h[pa]--; } void moveonto(int a,int pb,int b) { int i; for (i = 1; i <= h[pb]; i++) if (s[pb][i] == b) break; for (int j = h[pb]; j > i; j--) //j >= i s[pb][j+1] = s[pb][j]; s[pb][i+1] = a;//s[pb][i] = a; pos[a] = pb; h[pb]++; } void moveover(int a,int pb) { s[pb][++h[pb]] = a; pos[a] = pb; } void pileonto(int pa,int a,int pb,int b) { int i; for (i = 1; i <= h[pa]; i++) if (s[pa][i] == a) break; int j; for (j = 1; j <= h[pb]; j++) if (s[pb][j] == b) break; int sum = h[pa] - i + 1; for (int k = h[pb]; k > j; k--) s[pb][k+sum] = s[pb][k]; for (int k = j+1; i <= h[pa]; i++,k++) { int t = s[pa][i]; s[pb][k] = t; pos[t] = pb; } h[pa] -= sum; h[pb] += sum; } void pileover(int pa,int a,int pb,int b) { int i; for (i = 1; i <= h[pa]; i++) if (s[pa][i] == a) break; int sum = h[pa] - i + 1; for (; i <= h[pa]; i++) { int t = s[pa][i]; s[pb][++h[pb]] = t; pos[t] = pb; } h[pa] -= sum; } int main() { freopen("test.txt","r",stdin); int N; scanf("%d",&N); for (int i = 0; i <= 30; i++) { s[i][1] = i; h[i] = 1; pos[i] = i; } string cmd; int a,b,pa,pb; while (cin>>cmd,cmd != "quit") { if (cmd == "move") { cin>>a>>cmd>>b; pa = pos[a]; pb = pos[b]; if (pa == pb) continue; if (cmd == "onto") { remove(pa,a); moveonto(a,pb,b); } else { remove(pa,a); moveover(a,pb); } } else { cin>>a>>cmd>>b; pa = pos[a]; pb = pos[b]; if (pa == pb) continue; if (cmd == "onto") { pileonto(pa,a,pb,b); } else { pileover(pa,a,pb,b); } } } for (int i = 0; i < N; i++) { printf("%d:",i); for (int j = 1; j <= h[i]; j++) printf(" %d",s[i][j]); printf("\n"); } return 0; } /* 1/4 开始以为是道简单题,没多想就去写了。 1.开始题意给理解错了,把moveonto,A->B理解成了让a、b上其余的block都移动回最初的位置,题意其实是插入的意思; 2.a->b 开始写成了把a移动到第b堆,事实上b所在的堆 != 第b堆。 3.细节的把握,a-moveonto-b,a 是在b 的后面一个位置,而我写成了在b所在的位置 总之,对于稍复杂的模拟题做的不尽人意,加油~ */