BZOJ2214 [Poi2011]Shift

来源:互联网 发布:天球仪软件 编辑:程序博客网 时间:2024/05/19 20:21

假设现在序列中1~i-1已经有序地排在了一起,现在我们要考虑如何把i排到后边

我们先把i挪到第一位,然后我们只要保证i一直在第一位,然后把1~i-1窜到最后就可以了

我们可以每次进行两次a操作1次b操作就可以干掉后边的两个,而如果i-1后边只剩下了一个我们就可以进行1次a操作和两次b操作

但是这样的话当进行到i=n-1而n-1和n他们俩是逆序的时候会出问题,因为你把n-1挪到第一位的时候1也在前3位里,再按刚才那么搞的话1~i-1的顺序就乱了

我们发现这个时候n-1在第一位,n在最后一位,1~n-2在中间,我们只要保证中间不乱,把n-1挪到n前边就可以了

我们每次可以进行两次b操作,这样n-1就往后窜了两位,然后我们再把n-1挪到第一个,我们就可以继续进行两次b操作

可是当n为奇数的时候会出现最后n-1和n之间只有1个的情况

我们没办法搞,所以就无解了

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<ctime>#include<cmath>#include<algorithm>#include<iomanip>#include<vector>#include<map>#include<set>#include<bitset>#include<queue>#include<stack>using namespace std;#define MAXN 2010#define MAXM 1010#define INF 1000000000#define MOD 1000000007#define eps 1e-8#define ll long longint n,a[MAXN],p[MAXN],f[MAXN];int s;int tot;int c[MAXN*MAXN];bool o[MAXN*MAXN];int pos(int x){return (p[x]+s-1)%n+1;}int get(int x){return ((x-s-1)%n+n)%n+1;}void s1(int x){x%=n;if(!x){return ;}s+=x;c[++tot]=x;o[tot]=0;}void s2(){int p1=get(1);int p2=get(2);int p3=get(3);int x=f[p1];int y=f[p2];int z=f[p3];int t=p[x];p[x]=p[y];p[y]=p[z];p[z]=t;f[p[x]]=x;f[p[y]]=y;f[p[z]]=z;c[++tot]=1;o[tot]=1;}void print(){int ans=0;int i;for(i=1;i<=tot;i++){if(i==1||o[i]!=o[ans]){ans++;o[ans]=o[i];c[ans]=c[i];}else{c[ans]+=c[i];}}tot=ans;ans=0;for(i=1;i<=tot;i++){if(o[i]==0){c[i]%=n;}else{c[i]%=3;}if(c[i]){c[++ans]=c[i];o[ans]=o[i];}}printf("%d\n",ans);for(i=1;i<ans;i++){if(o[i]==0){printf("%da ",c[i]);}else{printf("%db ",c[i]);}}if(ans){if(o[i]==0){printf("%da\n",c[i]);}else{printf("%db\n",c[i]);}}}int main(){int i;scanf("%d",&n);if(n==1){printf("%d\n",0);return 0;}if(n==2){scanf("%d%d",&a[1],&a[2]);if(a[1]==1){printf("0\n");}else{printf("1\n1a\n");}return 0;}for(i=1;i<=n;i++){scanf("%d",&a[i]);p[a[i]]=i;f[i]=a[i];}for(i=2;i<=n-2;i++){s1(n-pos(i)+1);int t=n-pos(i-1);while(t>1){t-=2;s1(2);s2();}if(t){s1(1);s2();s2();}}if(n==3){s1(n-pos(1)+1);}if(f[get(2)]<f[get(3)]){s1(n-3);print();}else{if(!(n%2)){s1(n-2);for(i=1;i<n/2;i++){s2();s2();s1(n-2);}s1(n-2);print();}else{printf("NIE DA SIE\n");}}return 0;}/*65 2 1 6 3 4 */


0 0
原创粉丝点击