12657 - 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
Sample Output
Case 1: 12
Case 2: 9
Case 3: 2500050000

题解:

给你一个从1~n的数,然后给你操作方案

• 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.

用双向链表,用着刘汝佳的模版,却无限wa

我的wa代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
using namespace std;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
#define mem(x,y) memset(x,y,sizeof(x))
#define SI(x) scanf("%d",&x)
#define SL(x) scanf("%lld",&x)
#define PI(x) printf("%d",x)
#define PL(x) printf("%lld",x)
#define P_ printf(" ");
typedef long long LL;
const int MAXN=1e5+100;
int lef[MAXN],righ[MAXN];
void link(int l,int r){
lef[r]=l;
righ[l]=r;
}
int main(){
int n,m;
int s,x,y,kase=0;
while(~scanf("%d%d",&n,&m)){
for(int i=1;i<=n;i++){
lef[i]=i-1;
righ[i]=(i+1)%(n+1);
}
lef[0]=n;righ[0]=1;
int flot=0;
while(m--){
scanf("%d",&s);
if(s==4){
flot=!flot;
continue;
}
scanf("%d%d",&x,&y);
int lx=lef[x],rx=righ[x],ly=lef[y],ry=righ[y];
if(s!=3&&flot)s=3-s;
/****************************************/
if(s == 3 && righ[y] == x) swap(x, y);
if(s == 1 && x == lef[y]) continue;
if(s == 2 && x == righ[y]) continue;
/****************************************/
if(s==1){
link(lx,rx);link(ly,x);link(x,y);
}
else if(s==2){
link(lx,rx);link(y,x);link(x,ry);
}
else if(s==3){
if(righ[x] == y) { link(lx, y); link(y, x); link(x, ry); }
else {
link(lx,y);link(y,rx);link(ly,x);link(x,ry);
}
}
}
int cur=0;
LL ans=0;
for(int i=1;i<=n;i++){
cur=righ[cur];
if(i&1)ans+=cur;
}
if(flot&&n%2==0)ans=(LL)n*(n+1)/2-ans;
printf("Case %d: %lld\n",++kase,ans);
}
return 0;
}

  刘汝佳的ac代码:

#include<cstdio>
#include<algorithm>
using namespace std; const int maxn = 100000 + 5;
int n, left[maxn], right[maxn]; inline void link(int L, int R) {
right[L] = R; left[R] = L;
} int main() {
freopen("1.txt","r",stdin);
freopen("2.txt","w",stdout);
int m, kase = 0;
while(scanf("%d%d", &n, &m) == 2) {
for(int i = 1; i <= n; i++) {
left[i] = i-1;
right[i] = (i+1) % (n+1);
}
right[0] = 1; left[0] = n;
int op, X, Y, inv = 0; while(m--) {
scanf("%d", &op);
if(op == 4) inv = !inv;
else {
scanf("%d%d", &X, &Y);
if(op == 3 && right[Y] == X) swap(X, Y);
if(op != 3 && inv) op = 3 - op;
if(op == 1 && X == left[Y]) continue;
if(op == 2 && X == right[Y]) continue; int LX = left[X], RX = right[X], LY = left[Y], RY = right[Y];
if(op == 1) {
link(LX, RX); link(LY, X); link(X, Y);
}
else if(op == 2) {
link(LX, RX); link(Y, X); link(X, RY);
}
else if(op == 3) {
if(right[X] == Y) { link(LX, Y); link(Y, X); link(X, RY); }
else { link(LX, Y); link(Y, RX); link(LY, X); link(X, RY); }
}
}
} int b = 0;
long long ans = 0;
for(int i = 1; i <= n; i++) {
b = right[b];
if(i % 2 == 1) ans += b;
}
if(inv && n % 2 == 0) ans = (long long)n*(n+1)/2 - ans;
printf("Case %d: %lld\n", ++kase, ans);
}
return 0;
}

 再次比赛,出现了这个题,要注意,当两个数挨着的时候,要特判,否则会造成链表出乱,死循环,ac:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAXN = ;
typedef long long LL;
int L[MAXN], R[MAXN];
void link(int l, int r){
R[l] = r;
L[r] = l;
}
int main(){
int n, m;
int kase = ;
while(~scanf("%d%d", &n, &m)){
for(int i = ; i < n; i++){
link(i, i + );
}
L[] = n; R[n] = ;
int q, x, y;
int l, r, ll, rr;
int sw = ;
while(m--){
scanf("%d", &q);
if(q == ){
sw ^= ;
}
else{
scanf("%d%d", &x, &y);
if(q == || q == ){
if(sw)
q = - q;
}
if(q == && L[y] == x)
continue;
if(q == && R[y] == x)
continue;
if(q == ){
l = L[x]; r = R[x];
ll = L[y]; rr = R[y];
if(R[x] == y){
link(l, y);
link(y, x);
link(x, rr);
}
else if(R[y] == x){
link(ll, x);
link(x, y);
link(y, r);
}
else{
link(l, y); link(y, r);
link(ll, x); link(x, rr);
}
}
else if(q == ){
l = L[x]; r = R[x];
ll = L[y]; rr = R[y];
link(l, r);
link(y, x); link(x, rr);
}
else if(q == ){
l = L[x]; r = R[x];
ll = L[y]; rr = R[y];
link(l, r);
link(ll, x); link(x, y);
}
}
}
LL ans = ;
if(sw){
for(int i = L[], j = ; i ; i = L[i], j++){
if(j & )
ans += i;
}
}
else{
for(int i = R[], j = ; i ; i = R[i], j++){
if(j & )
ans += i;
}
}
printf("Case %d: %lld\n", ++kase, ans);
}
return ;
}

 

uva-12657 - Boxes in a Line(双向链表)的更多相关文章

  1. UVA 12657 Boxes in a Line 双向链表

    题目连接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=47066 利用链表换位置时间复杂度为1的优越性,同时也考虑到使用实际 ...

  2. 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 ...

  3. 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 ...

  4. UVA 12657 Boxes in a Line

    双向链表 注意:如果算法是最后处理翻转情况时,注意指令4翻转后1,2两个指令也要翻转处理: 指令3 中交换盒子要注意两个盒子相邻的情况 #include <iostream> #inclu ...

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

    题目链接 /* 问题 将一排盒子经过一系列的操作后,计算并输出奇数位置上的盒子标号之和 解题思路 由于数据范围很大,直接数组模拟会超时,所以采用数组模拟的链表,left[i]和right[i]分别表示 ...

  6. 2019 SCUT SE 新生训练第四波 L - Boxes in a Line——双向链表

    先上一波题目 https://vjudge.net/contest/338760#problem/L 这道题我们维护一个双向链表 操作1 2 3 都是双向链表的基本操作 4操作考虑到手动将链表反转时间 ...

  7. Boxes in a Line UVA - 12657

      You have n boxes in a line on the table numbered 1...n from left to right. Your task is to simulat ...

  8. 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 ...

  9. 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 sim ...

随机推荐

  1. (转载) css实现小三角(尖角)

    在各种网站里面,我们会经常看到类似于这样的尖角:(示例:新浪微博) 它实现的方式有多种,哪种才是最简单的?哪种才是最优秀的?首先我声明一下,我还不清楚这个东西具体叫什么名字(哪位知道还望告知),暂且叫 ...

  2. 让2个并列的div根据内容自动保持同等高度js

    有左右2个并列的div,2个div都不能限定高度.左div为导航,右div为内容.如何能让左div块自动获得和右div块相等的高度? 同时,也有网友提问到“如果右块高度比左块低,会不会导致左块的内容被 ...

  3. 防抖(Debouncing)和节流(Throttling)

    onscoll防抖封装函数 scroll 事件本身会触发页面的重新渲染,同时 scroll 事件的 handler 又会被高频度的触发, 因此事件的 handler 内部不应该有复杂操作,例如 DOM ...

  4. 利用JSP编程技术实现一个简单的购物车程序

    实验二   JSP编程 一.实验目的1. 掌握JSP指令的使用方法:2. 掌握JSP动作的使用方法:3. 掌握JSP内置对象的使用方法:4. 掌握JavaBean的编程技术及使用方法:5. 掌握JSP ...

  5. ubuntu 安装ruby rails

    步骤0 - 安装系统需要的包 Mac 请安装 Xcode 开发工具,它将帮你安装好 Unix 环境需要的开发包 Ubuntu 请安装 $ sudo apt-get install -y build-e ...

  6. asp.net mvc 注册中的邮箱激活功能实现(二)

    邮件发送功能封装 /// <summary>        /// 发送注册邮件        /// </summary>        /// <param name ...

  7. 转:CSS3 Flexbox 布局介绍

    转:CSS3 Flexbox 布局介绍 Flexbox是一个用于页面布局的全新CSS3模块功能.它可以把列表放在同一个方向(从左到右或从上到下排列),并且让这些列表能延伸到占用可用的空间.较为复杂的布 ...

  8. windows的命令行工具和DOS工具的区别

    很多的系统管理员可能认为命令行是程序员编程用的,这是不对的,其实命令行是另一种用来管理计算机的接口.1 命令行窗口        Windows NT/Windows 2000以后的操作系统为用户提供 ...

  9. Python开发技术详解(视频+源码+文档)

    Python, 是一种面向对象.直译式计算机程序设计语言.Python语法简捷而清晰,具有丰富和强大的类库.它常被昵称为胶水语言,它能够很轻松的把用其他语言制作的各种模块(尤其是C/C++)轻松地联结 ...

  10. 排序方法之标准库中的快排 qsort ()函数

    C标准库qsort()函数的用法(快排) 使用快速排序例程进行排序 头文件:stdlib.h 用 法: void qsort(void *base, int  nelem, int  width, i ...