您的位置:首页 > 其它

UVa 12657 Boxes in a Line

2015-03-20 11:40 323 查看
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

Sample Output

Case 1: 12

Case 2: 9
Case 3: 2500050000

思路很明确,用的双向链表。然后反转的时候记录反转位而不去反转整个链表也想到了,但是用指针来操作就会超时,不知为何。

以下代码为TLE,以后研究。

#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;

// 记录box及其位置结构体
typedef struct b_node
{
int num;
struct b_node* prev;
struct b_node* next;
}b_node;

// table[i]记录i所在的b_node
b_node* table[100100];

// 指向第一个box
b_node* first;

// 指向最后一个box
b_node* last;

void print_node();

int main()
{
int n, m;
int r_count = 1;
while(scanf("%d %d", &n, &m) == 2)
{
memset(table, 0, sizeof(table));
first = NULL;
last = NULL;
// 设置反转标志
// 如果为0,代表正常操作
// 如果为1,代表反转,操作相反
int rev_flag = 0;
// 将所有节点链在一起
for(int i = 1; i <= n; i++)
{
b_node* p = (b_node*)malloc(sizeof(b_node));
memset(p, 0, sizeof(p));
p->num = i;
if(first == NULL)
{
first = p;
last = p;
}
else
{
p->prev = last;
last->next = p;
last = p;
}
table[i] = p;
}

//print_node();

for(int i = 1; i <= m; i++)
{
int type, x1, x2;
scanf("%d", &type);
// 如果反转
if(rev_flag)
{
// 如果是向左,改为向右
if(type == 1)
type = 2;
// 如果是向右,改为向左
else if(type == 2)
type = 1;
}
// 如果将x1移到x2左边
if(type == 1)
{

scanf("%d%d", &x1, &x2);
b_node* p1 = table[x1];
b_node* p2 = table[x2];
// 如果p2左边无元素
if(p2->prev == NULL)
{
// 将p1原先的前后元素链在一起
if(p1->next != NULL)
p1->next->prev = p1->prev;
if(p1->prev != NULL)
p1->prev->next = p1->next;
if(p1 == last)
last = p1->prev;
// 将p1链在p2前面
p1->next = p2;
p1->prev = NULL;
p2->prev = p1;
first = p1;
}
// 如果p2左边有元素,且不是p1
else if(p2->prev != NULL && p2->prev->num != p1->num)
{
// 将p1原先的前后元素链在一起
if(p1->next != NULL)
p1->next->prev = p1->prev;
if(p1->prev != NULL)
p1->prev->next = p1->next;
if(p1 == last)
last = p1->prev;
if(p1 == first)
first = p1->next;

// 将p1链在p2前面
p1->next = p2;
p1->prev = p2->prev;
p2->prev->next = p1;
p2->prev = p1;
}

// print_node();
}
// 如果将x1移到x2右边
if(type == 2)
{
scanf("%d%d", &x1, &x2);
b_node* p1 = table[x1];
b_node* p2 = table[x2];

// 如果p2右边无元素
if(p2->next == NULL)
{
// 将p1原先的前后元素链在一起
if(p1->next != NULL)
p1->next->prev = p1->prev;
if(p1->prev != NULL)
p1->prev->next = p1->next;
if(p1 == first)
first = p1->next;
// 将p1链在p2后面
p1->prev = p2;
p1->next = NULL;
p2->next = p1;
// last = p1;
}
// 如果p2右边有元素,且不是p1
else if(p2->next != NULL && p2->next->num != p1->num)
{
// 将p1原先的前后元素链在一起
if(p1->next != NULL)
p1->next->prev = p1->prev;
if(p1->prev != NULL)
p1->prev->next = p1->next;
/* if(p1 == last)
last = p1->prev;
*/ if(p1 == first)
first = p1->next;

// 将p1链在p2前面
p1->prev = p2;
p1->next = p2->next;
p2->next->prev = p1;
p2->next = p1;
}

// print_node();
}
// 如果交换x1和x2
if(type == 3)
{
scanf("%d%d", &x1, &x2);
b_node* p1 = table[x1];
b_node* p2 = table[x2];

// 将p1前后的元素指向p2
if(p1->prev != NULL)
p1->prev->next = p2;
if(p1->next != NULL)
p1->next->prev = p2;
// 将p2前后的元素指向p1
if(p2->prev != NULL)
p2->prev->next = p1;
if(p2->next != NULL)
p2->next->prev = p1;

// 修改p1,p2各自指向的元素
b_node* p1_prev = p1->prev;
b_node* p1_next = p1->next;
p1->prev = p2->prev;
p1->next = p2->next;
p2->prev = p1_prev;
p2->next = p1_next;

// 如果可能的话,修改first,last
if(p1 == first)
first = p2;
/* if(p1 == last)
last = p2;
*/ if(p2 == first)
first = p1;
/* if(p2 == last)
last = p1;
*/
// print_node();
}
// 如果反转整个串
else if(type == 4)
{
// 修改反转标志位
if(rev_flag == 0)
rev_flag = 1;
else
rev_flag = 0;
/*
b_node* p = first;
// 将所有节点的前后指向相反
while(p != NULL)
{
// printf("now p: %d\n", p->num);
b_node* tmp = p->prev;
p->prev = p->next;
b_node* tmp_2 = p->next;
p->next = tmp;
p = tmp_2;
}

// 交换first,last
b_node* tmp = first;
first = last;
last = tmp;
*/
// print_node();
}
}

long long sum = 0;
// 遍历串,如果未反转,将奇数位的元素相加
// 如果反转,将偶数位的元素相加
b_node* p = first;
int count = 1;
while(p != NULL)
{
if(count % 2 != rev_flag)
sum += p->num;
p = p->next;
count++;
}
printf("Case %d: %lld\n", r_count, sum);
r_count++;
}
return 0;
}

void print_node()
{
b_node* p = first;
printf("now: ");
while(p != NULL)
{
printf("%d ",p->num);
p = p->next;
}
printf("\n");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: