问题 C: 序列交换
时间限制: 1 Sec 内存限制: 128 MB提交: 914 解决: 48
[提交] [状态] [命题人:jsu_admin]
题目描述
给一个 1 到 n 的排列,每次可以交换相邻两个数,问使用最少操作次数使得序列递增的方案是否唯一。
输入
多组输入,每组一个数n(1<=n<=10^5),然后是一个1~n的排列。
输出
方案唯一输出Yes,否则输出No。
样例输入 Copy
1 1 2 2 1 3 3 2 1
样例输出 Copy
Yes Yes No
比赛时数据出弱了,赛后加强了一下
为了使操作次数最少,每次都会交换相邻的逆序对。如果某时刻同时出现两个相邻逆 序对,方案数就不唯一了。不难发现,这个过程只能是把一个数不断向右挪到它最后 在
的位置上。这意味着最长上升子序列长度 ≥ n − 1。
1 #include <bits/stdc++.h> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cstring> 6 #include<cstdio> 7 #include<cmath> 8 //#define DEBUG 9 using namespace std; 10 typedef long long ll; 11 //typedef __int128 lll; 12 const int N=100000+100; 13 const int MOD=1e9+7; 14 const double PI = acos(-1.0); 15 const double EXP = 1E-8; 16 const int INF = 0x3f3f3f3f; 17 int t,n,m,k,q; 18 int a[N]; 19 int b[N]; 20 int main() 21 { 22 23 while(~scanf("%d",&n)){ 24 t=0; 25 for(int i=1;i<=n;i++){ 26 scanf("%d",&a[i]); 27 b[i]=a[i]; 28 if(i!=1&&a[i]<a[i-1]){ 29 t++; 30 } 31 } 32 if(t==1||t==0){ 33 if(t==1){ 34 for(int i=2;i<=n;i++){ 35 if(a[i]<a[i-1]){ 36 swap(a[i],a[i-1]); 37 //break; 38 } 39 } 40 for(int i=2;i<=n;i++){ 41 if(a[i]<a[i-1]){ 42 t=0; 43 break; 44 } 45 } 46 q=1; 47 for(int i=n;i>=2;i--){ 48 if(b[i]<b[i-1]){ 49 swap(b[i],b[i-1]); 50 //break; 51 } 52 } 53 for(int i=2;i<=n;i++){ 54 if(b[i]<b[i-1]){ 55 q=0; 56 break; 57 } 58 } 59 if(t||q){ 60 cout << "Yes" << endl; 61 }else{ 62 cout << "No" << endl; 63 } 64 }else{ 65 cout << "Yes" << endl; 66 } 67 }else{ 68 cout << "No" << endl; 69 } 70 } 71 72 return 0; 73 }