CodeForces 669D 构造

这个题啊,是N个男生和N个女生两两一对,顺时针围成一圈跳舞,女生位置不变,

初始时,男生1与女生1一对,男生2与女生2一对,,男生N与女生N一对。

男生有两种操作,一种是,所有男生顺时针移动x个位置(x为负则是逆时针移动),另一种是所有与奇数号(假设为x)女生的跳舞的男生与他相邻的号码为偶数(x+1)女生旁边的男生互换位置。操作一共有Q次。

然后问你最后每个女生旁边的男生各是几号

算是一个构造题吧,思维题。就是,首先能发现,1,3,5,7,9,,,所有的奇数男生是按这样的顺序围成一圈的,考虑第一种操作,不会打破这个圈,第二种操作,奇数号男生的排列顺序也不会改变,所以一直都是这个圈,同理,对于2,4,6,8,,,,的偶数男生也是一样。

所以,我们只需要知道1号男生在哪和2号男生在哪,就能知道所有男生分别在哪,就可以了。

假设1号男生位置为a1,2号男生位置为a2。第一种操作就是a1+=x,a2+=x;然后通过+-N使他们维持在[1,N]即可,至于第二种操作,稍微麻烦些,对于a1,判断它是奇数还是偶数,奇数就++,偶数就--,然后同样维持在[1,N]即可,a2也是同样。

最后,得到1号男生和2号男生位置,我是根据这个去反推出1号女生上是几号男生,2号女生上是几号男生,然后输出结果的,也可以,先求出所有男生在几号位置上,按位置存储男生信息,然后最后输出

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <set>
#include <map>
using namespace std;
#define ll long long
#define maxn 100005
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int n, q;
	int a1 = 1, a2 = 2;//记录男生1号和男生2号所在的位置
	int cmd, x;
	scanf("%d%d", &n, &q);
	for (int i = 0; i < q; ++i)
	{
		scanf("%d", &cmd);
		if (cmd == 1)
		{
			scanf("%d", &x);
			a1 += x; a2 += x;
			while (a1 <= 0)
				a1 += n;
			while (a1 > n)
				a1 -= n;
			while (a2 <= 0)
				a2 += n;
			while (a2 > n)
				a2 -= n;
		}
		else
		{
			if ((a1 & 1) > 0)
				++a1;
			else
				--a1;
			if ((a2 & 1) > 0)
				++a2;
			else
				--a2;
		}
		//printf("%d %d\n", a1, a2);
	}
	int t1, t2;//记录女生1和女生2位置上的男生序号
	if ((a1 & 1) > 0)
	{
		t1 = 1 - (a1 - 1) + n;
		t2 = 2 - (a2 - 2) + n;
	}
	else
	{
		t1 = 2 - (a2 - 1) + n;;
		t2 = 1 - (a1 - 2) + n;
	}
	while (t1 > n)
		t1 -= n;
	while (t2 > n)
		t2 -= n;
	for (int i = 1; i <= n / 2; ++i)
	{
		if (i == n / 2)
		{
			printf("%d %d\n", t1, t2);
		}
		else
		{
			printf("%d %d ", t1, t2);
			t1 += 2; t2 += 2;
			if (t1 > n)
				t1 -= n;
			if (t2 > n)
				t2 -= n;
		}
	}
	//system("pause");
	//while (1);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值