看了codeforces上的大神写的题解之后,才知道这道题水的根本!
不过相对前面两题来说,这道题的思维要难一点;
不过想到了水的根本,这题也真心不难;
方法嘛,就像剥洋葱一样,从外面往里面剥;
所以呢,dfs,每次往左或者往右找到乱序的那个元素,反转一下;
这样就行了,而且题目说了保证能够在三次内搞定;
证明我也不会,意思应该就是这样了!
1 #include<cstdio> 2 #include<vector> 3 #include<algorithm> 4 #define maxn 1009 5 using namespace std; 6 int a[maxn],n; 7 vector<int>l,r; 8 bool found=0; 9 int checkleft() 10 { 11 for(int i=1;i<=n;i++) 12 if(a[i]!=i) return i; 13 return -1; 14 } 15 int checkright() 16 { 17 18 for(int i=n;i>0;i--) 19 if(a[i]!=i) return i; 20 return -1; 21 } 22 int getpos(int x) 23 { 24 for(int i=1;i<=n;i++) 25 if(a[i]==x) return i; 26 } 27 void print() 28 { 29 printf("%d ",l.size()); 30 for(int i=l.size()-1;i>=0;i--) 31 printf("%d %d ",l[i],r[i]); 32 } 33 34 void dfs(int level) 35 { 36 if(checkleft()==-1) 37 { 38 print(); 39 found=1; 40 } 41 if(found||level==3) return; 42 int ll=checkleft(); 43 int pp=getpos(ll); 44 reverse(a+ll,a+pp+1); 45 l.push_back(ll); 46 r.push_back(pp); 47 dfs(level+1); 48 if(found) return; 49 reverse(a+ll,a+pp+1); 50 l.pop_back(); 51 r.pop_back(); 52 int rr=checkright(); 53 pp=getpos(rr); 54 reverse(a+pp,a+rr+1); 55 l.push_back(pp); 56 r.push_back(rr); 57 dfs(level+1); 58 if(found) return; 59 reverse(a+pp,a+rr+1); 60 l.pop_back(); 61 r.pop_back(); 62 } 63 64 int main() 65 { 66 scanf("%d",&n); 67 for(int i=1;i<=n;i++) 68 scanf("%d",&a[i]); 69 dfs(0); 70 return 0; 71 }