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");
}
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");
}
相关文章推荐
- 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(双向链表)
- 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(p144)----Boxes in a Line
- uva12657 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【双向链表】【数组模拟】
- UVA - 12657 Boxes in a Line
- Boxes in a Line UVA - 12657(关于双向链表)《求盒子的顺序》
- UVA 12657 Boxes in a Line (双向链表)
- UVA 12657 - Boxes in a Line
- 【例题 6-5 UVA 12657 】Boxes in a Line