C题: Constructive Problems Never Die
链接:https://ac.nowcoder.com/acm/contest/33192/C
题目大意 :** **给定长度为n的序列A,求排列P是的
∀
\forall
∀i,
P
i
P_i
Pi
≠
\ne
=
A
i
A_i
Ai。
长度为n的排列P定义为:长度为n且[1,n]区间内每个整数恰好出现一次的序列。
题解:
这题纯粹暴力…,首先我们假定
P
i
P_i
Pi=i,然后读入A,用一遍循环查询
P
i
P_i
Pi是否等于
A
i
A_i
Ai若相等
则在从同开始寻找是否有元素 j 可以与当前 i 互换;判断条件为if (p[j]!=p[i]&&p[i]!=a[j]);
当搜完一遍后发现没有交还则退出循环输出“”NO“,否则则输出P数组;
参考代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
using namespace std;
typedef long long ll;
int t,n,a[1000010],ans[1000010];
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
int l = 1;
for(int i=1;i<=n;i++){
ans[i] = i;
scanf("%d",&a[i]);
}
bool flag = 1;
for(int i=1;i<=n;i++){
if(a[i] == ans[i]){
flag = 0;
for(int j=1;j<=n;j++){
if(i != j && a[i] != ans[j] && a[j] != ans[i]){
swap(ans[i],ans[j]);
flag = 1;
break;
}
}
}
if(!flag) break;
}
if(!flag){
printf("NO\n");
continue;
}
else{
printf("YES\n");
for(int i=1;i<=n;i++){
printf("%d ",ans[i]);
}
printf("\n");
}
}
}