题目描述
You are given integer n. You have to arrange numbers from 1 to 2n, using each of them exactly once, on the circle, so that the following condition would be satisfied:
For every n consecutive numbers on the circle write their sum on the blackboard. Then any two of written on the blackboard 2n numbers differ not more than by 1.
For example, choose n=3. On the left you can see an example of a valid arrangement: 1+4+5=10, 4+5+2=11, 5+2+3=10, 2+3+6=11, 3+6+1=10, 6+1+4=11, any two numbers differ by at most 1. On the right you can see an invalid arrangement: for example, 5+1+6=12, and 3+2+4=9, 9 and 12 differ more than by 1.
示意图:左侧为正确的环,右侧为不满足条件的环
Input
The first and the only line contain one integer n (1≤n≤105).
Output
If there is no solution, output “NO” in the first line.
If there is a solution, output “YES” in the first line. In the second line output 2n numbers — numbers from 1 to 2n in the order they will stay in the circle. Each number should appear only once. If there are several solutions, you can output any of them.
题意
给了一个数n,要求将1-2n个数围城一个环,使得任意连续相连的n个数的和的差值不超过1,如果存在则输出这个环
题解
咋一看,立马想到当时做素数环的时候,想到应该dfs一下,但是感觉太麻烦,以C题来说,一般没有这么复杂,所以先大胆猜想一下
首先,因为是2*n,所以不难发现,如果n是偶数,那么环总是可以被分成两半,而且不可能任何时候左半边都等于右半边,所以显然如果n是偶数,那么必定无法形成环
那么,如果n是奇数的话,那么应该是可以形成的,我们可以推断一下。
首先,当n取1,那么显然就是1 2
当n取3,题目给了1 4 5 2 3 6(这个就很容易发现,1和2显然是应该处在一个对立的位置上,假设1是第一个,那么2一定是第n个,不然差值就会大于1)
然后可以发现,4 5, 2 3都是连着出现的,而这六个数已经形成了一个正确的环,那么如果数字变为5,我们可以根据3的六个数字,继续推算出剩下的四个数字位置(因为上面六个数已经满足条件了,我们根据推断又不难发现奇数都应该是满足条件的,那么我们将一个局部正确的环进行延伸,应该可以得到一个正确的拓展的环,所以不妨继续拓展一下)
那么 5的序列应该是1 4 5 8 9 2 3 6 7 10
至此,我们可以发现规律了,1后面的几个数的位置应该是固定的,而2后面几个数的位置也应该是固定的,每次都是上一次的延伸,那么不妨可以直接写出该数列,那么这个推断的数列就是答案了
#include <bits/stdc++.h>
using namespace std;
int a[200005];
int b[200005];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n,i,j,k;
long long t;
bool flag=0;
cin>>n;
if(n==1){
cout<<"YES"<<endl;
cout<<1<<" "<<2<<endl;//将1特判一下(其实也没有必要)
}
else if(n%2==0){
cout<<"NO"<<endl;//(偶数是必定不可以的)
}
else{
a[1]=1;
for(i=2;i<=2*n;i++){//(利用标记数组b来实现值的改变,因为是不断差3和不断加1的关系,在2处发生了改变)
if(b[i-1]==0){
if(a[i-1]!=2*n-1){
a[i]=a[i-1]+3;
//cout<<a[i]<<endl;
b[i]=1;
}
else if(a[i-1]==2*n-1){
a[i]=2;
b[i]=1;
}
}
if(b[i-1]==1){
a[i]=a[i-1]+1;
b[i]=0;
}
}
//for(i=1;i<=2*n;i++)
// cout<<a[i]<<" ";
cout<<"YES"<<endl;
for(i=1;i<=2*n;i++)
cout<<a[i]<<" ";
}
return 0;
}
所以不需要dfs就可以解决这个问题了
错误原因:看错题了!!!以为是连续三个数,结果一直wa,改了两个字母就ac了,错失了上分的良机…
加油