(双向链表之数组模拟)Boxes in a Line,第九届湖南省赛,B题
2014-08-20 11:31
471 查看
Problem B
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 Y (ignore this if X is already the right of Y)
3 X Y: swap box X and Y
4: reverse the whole line.
Commands are guaranteed to be valid, i.e. X will be not equal to Y.
For example, if n=6, after executing 1 1 4, the line becomes 2 3 1 4 5 6. Then after executing 2 3 5, the line becomes 2 1 4 5 3 6. Then after executing 3 1 6, the line becomes 2 6 4 5 3 1. Then after executing
4, then line becomes 1 3 5 4 6 2
Input
There will be at most 10 test cases. Each test case begins with a line containing 2 integers n, m(1<=n, m<=100,000). Each of the following m lines contain a command.Output
For each test case, print the sum of numbers at odd-indexed positions. Positions are numbered 1 to n from left to right.Sample Input
6 4 1 1 4 2 3 5 3 1 6 4 6 3 1 1 4 2 3 5 3 1 6 100000 1 4
Output for the Sample Input
Case 1: 12 Case 2: 9 Case 3: 2500050000
The Ninth Hunan Collegiate Programming Contest (2013)
Problemsetter: Rujia Liu
Special Thanks: Feng Chen, Md. Mahbubul Hasan
题意抽象:
一开始有的n个盒子(编号从1到n),进行m个操作.操作共四种:
1 X Y :将X盒子移到Y左边.
2 X Y :将X盒子移到Y右边.
3 X Y :交换X,Y盒子的位置.
4 :将全部盒子逆排.
要求最后位置标号为奇数的盒子的编号之和.
双向链表的数组模拟,水题,debug跨越了几天,无语......最后写一个数据生成器和暴力程序才过了.
这里也贴出数据生成器和暴力程序,给曾经也遭受此题调试折磨的童鞋带来福音.(用数据生成器生成测试数据,然后用暴力程序读入数据并生成标准答案,将标准答案与你程序的答案比较就可以找到你程序的错误数据了,最后再debug......(答案比较可使用cmd命令行的文件比较))
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 100005; typedef long long LL; int L[maxn], R[maxn]; bool direct; int N, M; int op, X, Y; void init() { for (int i = 1; i <= N; i++) { L[i] = i - 1; R[i] = i + 1; } R[0] = 1; L[N + 1] = N; direct = true; } void connect(int a, int b) { R[a] = b; L[b] = a; } void solve() { if (!direct && (op == 1 || op == 2)) op = 3 - op; if (op==3&&L[X] == Y) swap(X, Y); int lx = L[X], rx = R[X], ly = L[Y], ry = R[Y]; switch (op) { case 1: if (X == L[Y]) break; connect(lx, rx); connect(ly, X); connect(X, Y); break; case 2: if (X == R[Y]) break; connect(lx, rx); connect(Y, X); connect(X, ry); break; case 3: if (R[X] == Y) { connect(lx, Y); connect(Y, X); connect(X, ry); } else { connect(lx, Y); connect(Y, rx); connect(ly, X); connect(X, ry); } break; case 4: direct = !direct; break; } } int main() { /*freopen("f:\\input.txt", "r", stdin); freopen("f:\\test_in.txt", "r", stdin); freopen("f:\\OUT.txt", "w", stdout);*/ int cas = 0; while (scanf("%d%d", &N, &M) != EOF) { init(); while (M--) { cin >> op; if (op != 4) cin >> X >> Y; solve(); } LL ans = 0; for (int p = R[0],i=1; i<=N; p = R[p],i++) if (i%2==1) ans += p; if (!direct&&N % 2 == 0) ans = (LL)N / 2 * (LL)(N + 1)- ans; printf("Case %d: %lld\n", ++cas, ans); } return 0; }
数据生成器:
#include <iostream> #include <cstdio> #include <cstring> #include<ctime> #include<cstdlib> #include <algorithm> using namespace std; const int Test = 100; const int mod = 1000; typedef long long LL; int main() { freopen("f:\\test_in.txt", "w", stdout); //srand(time(NULL)); for (int i = 0; i < Test; i++) { int n = 1 + rand() % mod; int m = 1 + rand() % mod; cout << n << " " << m << endl; for (int j = 0; j < m; j++) { int op = 1 + rand() % 4; if (op == 4) { cout << op << endl; continue; } else { int x = 1 + rand() % n; int y = 1 + rand() % n; while (x == y) y = 1 + rand() % n; cout << op << " " << x << " " << y << endl; } } } }
暴力程序代码:
#include <iostream> #include <cstdio> #include <cstring> #include<ctime> #include<cstdlib> #include <algorithm> using namespace std; const int maxn = 1005; const int Test = 10; const int mod = 10; typedef long long LL; int a[maxn],b[maxn]; int *find(int *beg, int *end, int val) { while (*beg != val) beg++; return beg; } int main() { freopen("f:\\test_in.txt", "r", stdin); freopen("f:\\test_out.txt", "w", stdout); int n, m; int cas = 0; while (cin >> n >> m) { //bool dir = true; memset(a, 0, sizeof(a)); for (int i = 1; i <= n; i++) a[i] = i; for (int i = 0; i < m; i++) { int op, x, y,*xp,*yp,*p,tmp; cin >> op; if (op != 4) { cin >> x >> y; xp = find(a + 1, a + 1 + n, x); yp = find(a + 1, a + 1 + n, y); tmp = *xp; p = xp; } switch (op) { case 1: if (xp + 1 == yp) continue; if (xp < yp) { while (*(p + 1) != *yp) { *p = *(p + 1); p++; } *p = tmp; } else { while (*(p - 1) != *yp) { *p = *(p - 1); p--; } *p = *(p - 1); p--; *p = tmp; } break; case 2: if (xp - 1 == yp) continue; if (xp > yp) { while (*(p - 1) != *yp) { *p = *(p - 1); p--; } *p = tmp; } else { while (*(p + 1) != *yp) { *p = *(p + 1); p++; } *p = *(p + 1); p++; *p = tmp; } break; case 3: tmp = *xp; *xp = *yp; *yp = tmp; break; case 4: for (int j = n,k=1; j >= 1; j--,k++) b[j] = a[k]; for (int j = 1; j <= n; j++) a[j] = b[j]; break; } } LL ans = 0; for (int i = 1; i <= n; i+=2) ans += a[i]; printf("Case %d: %lld\n", ++cas, ans); } return 0; }
相关文章推荐
- 【数组模拟链表(双向)】UVA - 12657 Boxes in a Line
- UVa 12657 Boxes in a Line 数组模拟双向循环链表
- UVA12657 Boxes in a Line【双向链表】【数组模拟】
- UVa12657 - Boxes in a Line(数组模拟链表)
- 【日常学习】【模拟双向链表】【疑问】Uva12657 - Boxes in a Line题解
- UVa 12657 Boxes in a Line(双向链表的应用)
- UVA 12657 Boxes in a Line( 双向链表 )
- UVa 12657 Boxes in a Line(数组模拟双链表)
- UVA 12657 Boxes in a Line 【双向链表】
- UVa 12657 Boxes in a Line(双向链表的应用)
- 链表-双向链表&&UVa12657 Boxes in a Line(移动盒子)的理解与解析
- Uva12657 Boxes in a Line 【双向链表】【例题6-5】
- bnu 33967 Boxes in a Line 链表模拟
- 移动盒子(Boxes in a Line, UVa 12657) 关于STL中list(双向链表的应用)
- uva12657 Boxes in a Line 双向链表
- UVA 12657 Boxes in a Line 双向链表
- Uva 12657 Boxes in a Line 链表 模拟
- UVa 12657 Boxes in a Line(双向链表的应用)
- UVa 12657 - Boxes in a Line ( 双向链表 )
- UVA 12657 Boxes in a Line【双向链表】