您的位置:首页 > 其它

Codeforces Round #348 (VK Cup 2016 Round 2, Div. 2 Edition) D. Little Artem and Dance

2016-06-09 00:21 453 查看

题目链接:

http://codeforces.com/contest/669/problem/D

题意:

给你一个初始序列:1,2,3,...,n。

现在有两种操作:

1、循环左移,循环右移。

2、1,2位置交换,3,4位置交换,...,n-1,n位置交换

现在问执行了q次操作之后序列是什么,每次操作可以是两种操作的任意一种

题解:

我们把数列按位置的奇偶分为两堆,无论哪种操作,始终都还是这两堆,最多就是整堆的对换和一个堆内部的偏移。

所以我们只要记录第一个位置和第二个位置的数的变化(相当于每一堆的第一个数),那么后面的数都可以递推出来。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn = 1e6 + 10;
int arr[maxn];

int main() {
int n, q;
scanf("%d%d", &n, &q);
int a = 1, b = 2;
for (int i = 0; i < q; i++) {
int cmd;
scanf("%d", &cmd);
if (cmd == 1) {
int v; scanf("%d", &v);
int p = ((-v) % n + n) % n + 1;
int t1, t2;
if (p % 2) {
t1 = (a + p - 1 - 1 + n) % n + 1;
t2 = (b + p - 1 - 1 + n) % n + 1;
}
else {
t1 = (b + p - 2 - 1 + n) % n + 1;
t2 = (a + p - 1) % n + 1;
}
a = t1; b = t2;
}
else {
swap(a, b);
}
}
arr[1] = a, arr[2] = b;
for (int i = 3; i <= n; i++) {
arr[i] = (arr[i - 2] + 1) % n + 1;
}
for (int i = 1; i < n; i++) printf("%d ", arr[i]);
printf("%d\n", arr
);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: