Cube Stacking
Time Limit: 2000MS | Memory Limit: 30000K | |
Total Submissions: 21567 | Accepted: 7554 | |
Case Time Limit: 1000MS |
Description
Farmer John and Betsy are playing a game with N (1 <= N <= 30,000)identical cubes labeled 1 through N. They start with N stacks, each containing a single cube. Farmer John asks Betsy to perform P (1<= P <= 100,000) operation. There are two types of operations: moves and counts. * In a move operation, Farmer John asks Bessie to move the stack containing cube X on top of the stack containing cube Y. * In a count operation, Farmer John asks Bessie to count the number of cubes on the stack with cube X that are under the cube X and report that value. Write a program that can verify the results of the game.
Input
* Line 1: A single integer, P * Lines 2..P+1: Each of these lines describes a legal operation. Line 2 describes the first operation, etc. Each line begins with a 'M' for a move operation or a 'C' for a count operation. For move operations, the line also contains two integers: X and Y.For count operations, the line also contains a single integer: X. Note that the value for N does not appear in the input file. No move operation will request a move a stack onto itself.
Output
Print the output from each of the count operations in the same order as the input file.
Sample Input
6M 1 6C 1M 2 4M 2 6C 3C 4
Sample Output
102 题意:有n个从1到n编号的箱子,将每个箱子当做一个栈,对这些箱子进行p次操作,每次操作分别为以下两种之一: 1>输入 M x y:表示将编号为x的箱子所在的栈放在编号为y的箱子所在栈的栈顶. 2>输入 C x:计算编号为x的所表示的栈中在x号箱子下面的箱子数目. 题解:和龙珠那题一样,坑了半天,写的都醉了。。。 ac代码贴上:
1 #include2 #include 3 const int MAXN=30010; 4 int pre[MAXN],s[MAXN],dep[MAXN];//s数组存当前树的节点数; 5 int find(int x){ 6 if(x!=pre[x]){ 7 int t=pre[x]; 8 pre[x]=find(pre[x]); 9 dep[x]+=dep[t];10 }11 /* int i=x,j;12 while(i!=r){13 j=pre[i];pre[i]=r;i=j;14 }*/15 return pre[x];16 }17 void merge(int x,int y){18 int f1,f2;19 f1=find(x);f2=find(y);20 // printf("%d %d\n",f1,f2);21 if(f1!=f2){22 pre[f2]=f1;23 dep[f2]=s[f1]; 24 s[f1]+=s[f2];25 }26 }27 int main(){28 int N,x,y;29 char c[5];//定义成s了,错的啊。。。。 30 while(~scanf("%d",&N)){31 for(int i=1;i<=N;i++)pre[i]=i,dep[i]=0,s[i]=1;32 while(N--){33 scanf("%s",c);34 if(c[0]=='M'){35 scanf("%d%d",&x,&y);36 merge(x,y);37 }38 else {39 scanf("%d",&x);40 int px=find(x);41 // printf("s[%d]=%d %d\n",px,s[px],dep[x]);42 printf("%d\n",s[px]-dep[x]-1);43 }44 }45 }46 return 0;47 }
另一种解法超时:
1 #include2 #include 3 const int MAXN=300010; 4 int pre[MAXN],s[MAXN];//s数组存当前树的节点数; 5 int find(int x){ 6 while(x!=pre[x]) 7 x=pre[x]; 8 return x; 9 }10 void merge(int x,int y){11 int f1,f2;12 f1=find(x);f2=find(y);13 if(f1!=f2){14 pre[f2]=f1;15 s[f1]+=s[f2];16 }17 }18 int getdep(int x){19 int s=0;20 while(x!=pre[x]){21 x=pre[x];22 s++;23 }24 return s;25 }26 int main(){27 int N,x,y;28 char c[5];//定义成s了,错的啊。。。。 29 while(~scanf("%d",&N)){30 for(int i=1;i<=N;i++)pre[i]=i,s[i]=1;31 while(N--){32 scanf("%s",c);33 if(c[0]=='M'){34 scanf("%d%d",&x,&y);35 merge(x,y);36 }37 else {38 scanf("%d",&x);39 int px=find(x);40 int d=getdep(x);41 printf("%d\n",s[px]-d-1);42 }43 }44 }45 return 0;46 }