您的位置:首页 > 其它

(双向链表之数组模拟)Boxes in a Line,第九届湖南省赛,B题

2014-08-20 11:31 465 查看

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: