NYOJ-511-移动小球

来源:互联网 发布:linux tail 最后一页 编辑:程序博客网 时间:2024/03/29 22:22

http://acm.nyist.net/JudgeOnline/problem.php?pid=511

这道题很容易想到要构建一个循环链表来确定每个球的相对位置,就是操作比较繁琐,考虑情况较多。

首先要创建节点Node,每个节点都有一个初始顺序order,指向左边的Node*指针left,何指向右边的Node*指针right。

[cpp] view plaincopyprint?
  1. struct Node  
  2. {  
  3.     int order;  
  4.     Node *left,*right;  
  5. }node[N];  

然后给每个小球附上顺序,并建立和左右的联系。

[cpp] view plaincopyprint?
  1. void build(int n)  
  2. {  
  3.     int i,order=1;  
  4.     for(i=1;i<n;i++)  
  5.         {  
  6.             node[i].order=i;  
  7.             node[i].right=&node[i+1];  
  8.             node[i+1].left=&node[i];  
  9.         }  
  10.     node[1].left=&node[n];  
  11.     node[n].right=&node[1];  
  12.     node[n].order=n;  
  13. }  然后就是A、B操作,下边叙述一下A操作(将x放在y左边)的实现方法:

1.将x左边节点的right指针指向x的右边节点

2.将x右边节点的left指针指向x的左边节点

3.将x的right指向y节点

4.将x的left指向y左边的节点

5.将y左边节点的right指向x节点

6.将y的left指向x节点

实现代码:

[cpp] view plaincopyprint?
  1. void A(int x,int y)  
  2. {  
  3.     Node *p=&node[x],*q=&node[y];  
  4.     p->left->right=p->right;  
  5.     p->right->left=p->left;  
  6.     p->left=q->left;  
  7.     p->right=q;  
  8.     q->left->right=p;  
  9.     q->left=p;  
  10. }  由于交换位置仅改变节点的左右指针,并没有改变数组的下标(下标其实与order相同),所以查找球号时直接用下标索引。

同理可知操作B。

完整代码如下:

[cpp] view plaincopyprint?
  1. #include<stdio.h>   
  2. const int N=10005;  
  3. struct Node  
  4. {  
  5.     int order;  
  6.     Node *left,*right;  
  7. }node[N];  
  8. void build(int n)  
  9. {  
  10.     int i,order=1;  
  11.     for(i=1;i<n;i++)  
  12.         {  
  13.             node[i].order=i;  
  14.             node[i].right=&node[i+1];  
  15.             node[i+1].left=&node[i];  
  16.         }  
  17.     node[1].left=&node[n];  
  18.     node[n].right=&node[1];  
  19.     node[n].order=n;  
  20. }  
  21. void A(int x,int y)  
  22. {  
  23.     Node *p=&node[x],*q=&node[y];  
  24.     p->left->right=p->right;  
  25.     p->right->left=p->left;  
  26.     p->left=q->left;  
  27.     p->right=q;  
  28.     q->left->right=p;  
  29.     q->left=p;  
  30. }  
  31. void B(int x,int y)  
  32. {  
  33.     Node *p=&node[x],*q=&node[y];  
  34.     p->left->right=p->right;  
  35.     p->right->left=p->left;  
  36.     p->right=q->right;  
  37.     q->right->left=p;  
  38.     p->left=q;  
  39.     q->right=p;  
  40. }  
  41. int main()  
  42. {  
  43.     int ncase,n,m,i;  
  44.     char cmd;  
  45.     int x,y;  
  46.     scanf("%d",&ncase);  
  47.     while(ncase--)  
  48.     {  
  49.         scanf("%d%d",&n,&m);  
  50.         build(n);  
  51.         while(m--)  
  52.         {  
  53.             scanf("%*c%c%d%d",&cmd,&x,&y);  
  54.             switch(cmd)  
  55.             {  
  56.             case 'A':  
  57.                 A(x,y);break;  
  58.             case 'B':  
  59.                 B(x,y);break;  
  60.             case 'Q':  
  61.                 printf("%d\n",x?node[y].right->order:node[y].left->order);break;  
  62.             }  
  63.         }  
  64.     }  
  65.     return 0;  
  66. }  
其实此题还可以不用链表,对比了一下,时间相差不大,相比而言非链表法更不容易出错。

思路基本一样,直接给出代码:

[cpp] view plaincopyprint?
  1.    
  2. #include<cstdio>   
  3. const int N=10005;  
  4. struct xyz  
  5. {  
  6.     int prv,nxt;  
  7. }a[N];  
  8. void build(int n)  
  9. {  
  10.     int i;  
  11.     for(i=1;i<=n;i++)  
  12.         {  
  13.             a[i].prv=i-1;  
  14.             a[i].nxt=i+1;  
  15.         }  
  16.     a[1].prv=n;  
  17.     a[n].nxt=1;  
  18. }  
  19. void A(int x,int y)  
  20. {  
  21.     a[a[x].prv].nxt=a[x].nxt;  
  22.     a[a[x].nxt].prv=a[x].prv;  
  23.     a[x].nxt=y;  
  24.     a[x].prv=a[y].prv;  
  25.     a[a[y].prv].nxt=x;  
  26.     a[y].prv=x;  
  27. }  
  28. void B(int x,int y)  
  29. {  
  30.     a[a[x].prv].nxt=a[x].nxt;  
  31.     a[a[x].nxt].prv=a[x].prv;  
  32.     a[x].nxt=a[y].nxt;  
  33.     a[x].prv=y;  
  34.     a[a[y].nxt].prv=x;  
  35.     a[y].nxt=x;  
  36. }  
  37. int main()  
  38. {  
  39.     int ncase,n,m,i;  
  40.     char cmd;  
  41.     int x,y;  
  42.     scanf("%d",&ncase);  
  43.     while(ncase--)  
  44.     {  
  45.         scanf("%d%d",&n,&m);  
  46.         build(n);  
  47.         while(m--)  
  48.         {  
  49.             scanf("%*c%c%d%d",&cmd,&x,&y);  
  50.             switch(cmd)  
  51.             {  
  52.             case 'A':  
  53.                 A(x,y);break;  
  54.             case 'B':  
  55.                 B(x,y);break;  
  56.             case 'Q':  
  57.                 printf("%d\n",x?a[y].nxt:a[y].prv);break;  
  58.             }  
  59.         }  
  60.     }  
  61.     return 0;  
  62. }  
  63.           
原创粉丝点击