"蔚来杯"2022牛客暑期多校训练营7 C-Constructive Problems Never Die

问题描述

Grammy has a sequence A of length n.
Please find a permutation P such that Pi≠Ai for all i.

输入格式

There are multiple test cases.
The first line contains a single integer T (1≤T≤100000), denoting the number of test cases.
For each test case:
The first line contains a single integer n (1≤n≤100000).
The second line contains n integers A1​,A2​,…,An​ (1≤Ai​≤n).
It is guaranteed that the sum of n does not exceed 500000.

输出格式

For each test case:
If the permutation does not exist, output “NO” in one line.
Otherwise output “YES” in the first line, then output n integers in the second line, denoting the permutation P1​,P2​,…,Pn​.

样例输入

3
3
3 3 3
3
3 2 1
6
1 1 4 5 1 4

样例输出

NO
YES
1 3 2
YES
4 5 1 2 3 6

题解

给定一个序列a,求一个全排列p,满足p[i]!=a[i]

若a中每个数都相等,则无论怎样的排列一定会存在一个p[i]==a[i]

只要序列a中存在一个不同的数,就一定存在满足条件的全排列

先假设一个初始全排列b[i]=i,对于b中某个不满足条件的位置j(即a[j]==b[j]),由于b[j]和b[j+1]不相等,若a[j]==b[j],则a[j]和b[j+1]一定不等,交换b[j]和b[j+1],就能使b[j]满足条件;若b中最后一个数不满足条件,此时无法通过和下一个交换使其满足条件,我们可以从前面满足条件的位置中找一个和b[n]交换仍然满足条件的位置进行交换

 

 

 1 #include <cstring>
 2 #include <cstdio>
 3 int T,n,a[100005],b[100005];
 4 int cnt[100005],p[100005],t;
 5 int main()
 6 {
 7     int i,j;
 8     scanf("%d",&T);
 9     while (T--)
10     {
11         memset(cnt,0,sizeof(cnt));
12         t=0;
13         scanf("%d",&n);
14         for (i=1;i<=n;i++)
15           scanf("%d",&a[i]),
16           b[i]=i,cnt[a[i]]++;
17         for (i=1;i<=n;i++)
18         {
19             if (cnt[i]==n) break;
20             if (b[i]!=a[i])
21             {
22                 p[++t]=i;
23                 continue;
24             }
25             if (i!=n)
26             {
27                 b[i]^=b[i+1];
28                 b[i+1]^=b[i];
29                 b[i]^=b[i+1];
30                 p[++t]=i;
31                 continue;
32             }
33             for (j=1;j<=t;j++)
34               if (b[p[j]]!=a[n] && b[n]!=a[p[j]])
35               {
36                   b[p[j]]^=b[n];
37                   b[n]^=b[p[j]];
38                   b[p[j]]^=b[n];
39                   break;
40               }
41         }
42         if (i==n+1)
43         {
44             printf("YES\n");
45             for (j=1;j<n;j++)
46               printf("%d ",b[j]);
47             printf("%d\n",b[n]);
48         } 
49         else printf("NO\n");
50     }
51     return 0;
52 } 

 

posted @ 2022-08-20 21:17  SAKURA12  阅读(37)  评论(0编辑  收藏  举报