UVa 12657 Boxes in a Line(数组模拟双链表)

题目链接

 1 /*
 2 问题
 3 将一排盒子经过一系列的操作后,计算并输出奇数位置上的盒子标号之和
 4
 5 解题思路
 6 由于数据范围很大,直接数组模拟会超时,所以采用数组模拟的链表,left[i]和right[i]分别表示i号盒子的左边是谁和右边
 7 是谁。特别提醒,4这个操作可以采用其他的办法去标记,而不必真的去模拟交换,否则会超时。
 8 */
 9
10 #include<cstdio>
11 #include<algorithm>
12
13 using namespace std;
14 const int maxn=101000;
15 int n,left[maxn],right[maxn];
16
17 void link(int r,int l);
18
19 int main()
20 {
21     //freopen("E:\\testin.txt","r",stdin);
22     int m,i,kase=1;
23     while(scanf("%d%d",&n,&m) != EOF){
24         for(i=0;i<=n;i++){
25             link(i,i+1);
26         }
27         left[0]=n;
28         right[n]=0;
29
30         int op,x,y;
31         int inv=0;
32         while(m--){
33             scanf("%d",&op);
34             if(op == 4)    inv= !inv;
35             else{
36                 scanf("%d%d",&x,&y);
37                 if(op == 3 && right[y] == x) swap(x,y);
38                 if(op != 3 && inv) op= 3-op;
39                 if(op == 1 && x==left[y])    continue;
40                 if(op == 2 && x==right[y])    continue;
41
42                 int lx=left[x],rx=right[x],ly=left[y],ry=right[y];
43                 if(op == 1){
44                     link(lx,rx);
45                     link(ly,x);
46                     link(x,y);
47                 }else if(op == 2){
48                     link(lx,rx);
49                     link(y,x);
50                     link(x,ry);
51                 }else if(op == 3){
52                     if(right[x] == y){
53                         link(y,x);
54                         link(lx,y);
55                         link(x,ry);
56                     }
57                     else{
58                         link(lx,y);
59                         link(y,rx);
60                         link(ly,x);
61                         link(x,ry);
62                     }
63                 }
64             }
65         }
66
67         int cou=0;
68         long long ans=0;
69         for(int i=1;i<=n;i++){
70             cou=right[cou];
71             //printf("#%d\n",cou);
72             if(i%2 == 1)
73                 ans += cou;
74         }
75         if(inv && n%2 == 0)    ans = (long long)n*(n+1)/2 - ans;
76         printf("Case %d: %lld\n",kase++,ans);
77     }
78     return 0;
79 }
80
81 void link(int l,int r)
82 {
83     right[l]=r;
84     left[r]=l;
85 }

原文地址:https://www.cnblogs.com/wenzhixin/p/9129728.html

时间: 2024-10-12 14:12:37

UVa 12657 Boxes in a Line(数组模拟双链表)的相关文章

uva 12657 - Boxes in a Line(AC和TLE的区别,为什么说STL慢..)

用STL中的list写的,TLE #include<cstdio> #include<iostream> #include<cstring> #include<list> #include<algorithm> using namespace std; list<int> l; list<int>::iterator it1,it2,it3,it4,it5,it; void work(int a,int a1=1,int

UVa 12657 Boxes in a Line(双向链表的应用)

Boxes in a Line You have n boxes in a line on the table numbered 1 . . . n from left to right. Your task is to simulate 4 kinds of commands: ? 1 X Y : move box X to the left to Y (ignore this if X is already the left of Y ) ? 2 X Y : move box X to th

UVa12657 - Boxes in a Line(数组模拟链表)

题目大意 你有一行盒子,从左到右依次编号为1, 2, 3,…, n.你可以执行四种指令: 1 X Y表示把盒子X移动到盒子Y左边(如果X已经在Y的左边则忽略此指令).2 X Y表示把盒子X移动到盒子Y右边(如果X已经在Y的右边则忽略此指令).3 X Y表示交换盒子X和Y的位置.4 表示反转整条链. 盒子个数n和指令条数m(1<=n,m<=100,000) 题解 用数组来模拟链表操作,对于每个节点设置一个前驱和后继. 1操作是把x的前驱节点和x的后继节点连接,y节点的前驱和x节点连接,x节点和y

UVa 12657 Boxes in a Line(应用双链表)

Boxes in a Line You have n boxes in a line on the table numbered 1 . . . n from left to right. Your task is to simulate 4 kinds of commands: ? 1 X Y : move box X to the left to Y (ignore this if X is already the left of Y ) ? 2 X Y : move box X to th

UVA 12657 Boxes in a Line

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4395 题目意思是说,给出一个数n,表示存在一个整数序列1--n,然后进行四种操作: 操作一:输入x,y,表示将x移到y的左边(若x本来就在y的左边则忽略): 操作二:输入x,y,表示将x移到y的右边(若x本来就在y的右边则忽略): 操作三:输入x,y,表示交换x和y. 操作四:将

Uva 12657 Boxes in a Line 双向链表

操作4比较特殊,为了避免一次性修改所有元素的指针,由于题目只要求输出奇数盒子的编号,所以我们可以灵活的根据是否进行过操作4对操作1 操作2 进行改动 操作3不受操作4影响 上代码.... #include<cstdio> #include<algorithm> const int maxn=100000+5; int right[maxn],left[maxn]; void link (int L,int R){ right[L]=R;left[R]=L; } //在双向链表这样复

UVA 12657 Boxes in a Line(双向链表+小技巧)

题意:对于一行按照顺序排列盒子数字与位置都为 1,2,3,4....n 执行四种操作 c = 1    x 放到 y 的左边 c =2     x 放到 y 的右边 c =3 交换 x, y c =4 颠倒链 最后求出奇数位置的数的总和 题解:直接维护无论如何每次每次都需要维护一段区间的位置,因此不去看位置.只需要知道每个盒子左边是哪个盒子右边是哪个盒子 这样就直接使用双向链表维护,接着颠倒时注意只是标记就好 最后注意几个细节: 首先颠倒后1与2的交换需要互换: 维护链表时可以提取出一个函数,每

12657 - Boxes in a Line

Boxes in a Line You have n boxes in a line on the table numbered 1-n from left to right. Your task is to simulate 4 kinds of commands: 1 X Y : move box X to the left to Y (ignore this if X is already the left of Y) 2 X Y : move box X to the right to

数组模拟单向链表例题(UVa11988)

指针的链表实现方式是,当前节点的next指向下一个节点,用数组模拟就是 for(int i=next[0];i!=0;i=next[i]) i=next[i]:就是一条链. 例题: 你有一个破损的键盘.键盘上的所有键都可以正常工作,但有时Home键或者End键会自动按下.你并不知道键盘存在这一问题,而是专心打稿子,甚至连显示器都没打开.当你打开显示器时之后,展现在你面前的是一段悲剧文本.你的任务时在打开显示器之前计算出这段悲剧文本. 输入包含多组数据.每组数据占一行,包含不超过100000个字母