BNUoj 26474 Bread Sorting

来源:互联网 发布:飞控电子显示屏软件 编辑:程序博客网 时间:2024/06/07 04:57

http://www.bnuoj.com/bnuoj/problem_show.php?pid=26474

/*给出n个原始顺序的数,再给出要排成目标状态顺序,每次从第一个数列中选择三个,把这三个数中最右边的数放在最左边,然后其他两个数右移一个单位,为你从原始状态能不能排序成目标状态。本人YY的结论,从特殊到一般,虽然一般的只是手证了数值比较小的:结论应该就是1到n的n个数的全排列,分成相等的奇排序和偶排序,且个数一样,同个集合中的排列可以互相转换比如1 2 3 4的全排1 2 3 41 4 2 31 3 4 24 1 3 24 2 1 34 3 2 12 4 3 12 1 4 32 3 1 43 4 1 2(可由4 1 3 2变成,一样的)3 2 4 13 1 2 4这个偶排序占了12个,其他十二个是奇排序所以这道题直接比较两个数列的奇偶性*/#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int maxn=100010;int a[maxn],b[maxn],c[maxn];int n;struct point{int num,index;}p[maxn];int cmp(const point a,const point b){return a.num<b.num;}int lowbit(int x){return x&(-x);}void updata(int i,int x){while(i<=n){c[i]+=x;i=i+lowbit(i);}}int sum(int x){int ans=0;while(x>0){       ans+=c[x];   x=x-lowbit(x);}return ans;}int main(){int i,j;while(scanf("%d",&n)!=EOF){memset(c,0,sizeof(c));for(i=1;i<=n;i++){scanf("%d",&p[i].num);p[i].index=i;}sort(p+1,p+n+1,cmp);        for(i=1;i<=n;i++)b[p[i].index]=i;int ans1=0,ans2=0;for(i=1;i<=n;i++){updata(b[i],1);ans1=ans1+(sum(n)-sum(b[i]));//sum(p[i])是前面比b[i]小的数的个数}    memset(c,0,sizeof(c));        memset(p,0,sizeof(p));memset(b,0,sizeof(b));for(i=1;i<=n;i++){scanf("%d",&p[i].num);p[i].index=i;}sort(p+1,p+n+1,cmp);        for(i=1;i<=n;i++)b[p[i].index]=i;for(i=1;i<=n;i++){updata(b[i],1);ans2=ans2+(sum(n)-sum(b[i]));}printf("%d %d\n",ans1,ans2);if(ans1%2==ans2%2) printf("Possible\n");else printf("Impossible\n");}return 0;}PS:这道题置换群也可以破有奇数个有偶数个元素的轮换就是不可以有偶数个有偶数个元素的轮换就是可以