牛牛与交换排序
题目链接:https://ac.nowcoder.com/acm/contest/9982/F
思路: 首先找出第一个i!=a[i] 的位置确定长度
然后考虑用双端队列来维护 翻转的操作, 即翻转一次我们就变为以尾为头, 再翻一次变成以头为头即可
写好翻转偶数次的操作后 复制一遍所有的front改成back back改成front 即是翻转奇数次的操作了
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5+10; 4 const int mod=998244353; 5 #define ll long long 6 #define pi pair<int,int> 7 #define fi first 8 #define sc second 9 #define pb push_back 10 int a[maxn],p[maxn]; 11 12 int main() 13 { 14 ios::sync_with_stdio(0); 15 cin.tie(0); 16 int n; 17 cin>>n; 18 for(int i=1;i<=n;i++) cin>>a[i]; 19 for(int i=1;i<=n;i++) p[a[i]]=i; 20 int k=0; 21 for(int i=1;i<=n;i++) 22 { 23 if(p[i]!=i) 24 { 25 k=p[i]-i+1; 26 break; 27 } 28 } 29 if(k==0) 30 { 31 cout<<"yes"<<'\n'<<1<<'\n'; 32 return 0; 33 } 34 deque<int>q; 35 for(int i=1;i<=k;i++) q.push_back(a[i]); 36 int f=0; 37 for(int i=1;i<=n;i++) 38 { 39 if(!f) 40 { 41 if(q.front()!=i) 42 { 43 if(q.back()!=i||i>n-k+1) 44 { 45 cout<<"no"<<'\n'; 46 return 0; 47 } 48 f=!f; 49 q.pop_back(); 50 if(i+k<=n) 51 q.push_front(a[i+k]); 52 continue; 53 } 54 q.pop_front(); 55 if(i+k<=n) 56 q.push_back(a[i+k]); 57 } 58 else 59 { 60 if(q.back()!=i) 61 { 62 if(q.front()!=i||i>n-k+1) 63 { 64 cout<<"no"<<'\n'; 65 return 0; 66 } 67 f=!f; 68 q.pop_front(); 69 if(i+k<=n) 70 q.push_back(a[i+k]); 71 continue; 72 } 73 q.pop_back(); 74 if(i+k<=n) 75 q.push_front(a[i+k]); 76 } 77 } 78 cout<<"yes"<<'\n'<<k<<'\n'; 79 80 81 82 83 }

浙公网安备 33010602011771号