luogu P9741 「KDOI-06-J」翻转与反转

题目

小 W 有一个长度为 n 的 01 序列 a1​,a2​,…,an​,他将对这个序列按顺序进行 n 次操作。

在第 i 次操作中(1≤i≤n),小 W 将按顺序执行以下两种变换:

  1. 将区间[1,i] 中的数按下标翻转。形式化地说,在这次变换之后,序列 a 将变为ai​,ai−1​,…,a1​,ai+1​,ai+2​,…,an​。
  2. 将区间 [1,i] 中的数按值翻转。形式化地说,在这次变换之后,对于任意 1≤j≤i,若 aj​=0,则aj​ 将变为 1,否则 aj​ 将变为 0。

小 W 想要知道,在全部n 次操作结束后,序列 a 中每个元素的值。

输入格式

从标准输入读入数据。

输入的第一行包含一个正整数 n,表示序列长度。

接下来一行 n 个整数,表示序列 a1​,a2​,…,an​。保证 ai​=0 或 1。

输出格式

输出到标准输出。

输出包含一行 n个整数,表示操作结束后序列 a 中每个元素的值。

解题思路:

每次转换时,变换2会把数位上的数字会把数位上的数字来回变换,因此可以发现当一个数经过偶数次变换即不用变换,奇数才应该变换。由于有时间限制,变换1,我们也应找规律:

1 2 3 4 5 6 7 

2 1 3 4 5 6 7

3 1 2 4 5 6 7

4 2 1 3 5 6 7

5 3 1 2 4 6 7

6 4 2 1 3 5 7

7 5 3 1 2 4 6

经过观察·发现如下规律:若为偶数次变换,    b[i+p/2]=a[i];若为奇数次变换则为    b[i-(i-1)+p/2]=a[i];p为变换次数,    p=n-i+1;

代码如下:

#include<bits/stdc++.h>
using namespace std;
int a[2000010];
int b[2000010];
int main()
{
	int n,p;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	for(int i=1;i<=n;i++)
	{
		p=n-i+1;
		if(p%2==0)
		{
			b[i+p/2]=a[i];
		}
		else
		{
			if(a[i]==0)
			a[i]=1;
			else
			a[i]=0;
			b[i-(i-1)+p/2]=a[i];
		}
	}
	for(int i=1;i<=n;i++)
	{
		cout<<b[i]<<" ";
	}
	cout<<endl;
}

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值