题目
小 W 有一个长度为 n 的 01 序列 a1,a2,…,an,他将对这个序列按顺序进行 n 次操作。
在第 i 次操作中(1≤i≤n),小 W 将按顺序执行以下两种变换:
- 将区间[1,i] 中的数按下标翻转。形式化地说,在这次变换之后,序列 a 将变为ai,ai−1,…,a1,ai+1,ai+2,…,an。
- 将区间 [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;
}