[CF804E]The same permutation

版权声明:本文是蒟蒻写出来的,神犇转载也要说一声哦! https://blog.csdn.net/WerKeyTom_FTD/article/details/80556799

题目大意

一个长度为n的排列,现在你要构造一个长度为n(n1)2的操作序列,每个操作形如(x,y)满足x<y,其效果是交换第x和第y个位置。每种本质不同的操作只能用一次。
这个操作序列需要满足,从头开始执行,最终序列变回原样。
要求判断无解。

做法

先考虑如何判断无解。
n mod 4>1时是无解的,此时操作序列长度是奇数。
可以发现,每次交换操作都会改变逆序对的奇偶性,因此操作序列长度为奇数显然无解。
其余情况均有解。
先考虑n=4的解:
1 2 3 4
3 4 1 2
2 1 4 3
1 2 3 4
然后考虑n=5的解:
1 2 3 4 5
5 1 3 4 2
3 4 5 1 2
3 4 1 2 5
2 1 4 3 5
1 2 3 4 5
现在考虑n是4的倍数怎么做:
4个为一块,分成若干块。
每个块内内部做一遍n=4
然后任意两块间尝试用完所有操作,且分别不变:
块内两个为一单位再隔开,然后每次从不同块里分别找一个单位,先交叉互换,再对应换回。
那么n模4余1也很好做了,只需要把n和每块做一遍n=5

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=1000+10;
int a[4],b[4];
int i,j,k,l,t,n,m;
void work(){
    int i,j,l,r;
    fo(i,0,1)
        fo(j,0,1){
            l=i*2;r=j*2;
            printf("%d %d\n",a[l],b[r+1]);
            printf("%d %d\n",a[l+1],b[r]);
            printf("%d %d\n",a[l],b[r]);
            printf("%d %d\n",a[l+1],b[r+1]);
        }
}
void solve4(){
    printf("%d %d\n",a[0],a[2]);
    printf("%d %d\n",a[1],a[3]);
    printf("%d %d\n",a[0],a[3]);
    printf("%d %d\n",a[1],a[2]);
    printf("%d %d\n",a[0],a[1]);
    printf("%d %d\n",a[2],a[3]);
}
void solve5(){
    printf("%d %d\n",a[0],n);
    printf("%d %d\n",a[1],n);
    printf("%d %d\n",a[0],a[2]);
    printf("%d %d\n",a[1],a[3]);
    printf("%d %d\n",a[3],n);
    printf("%d %d\n",a[2],n);
    printf("%d %d\n",a[0],a[3]);
    printf("%d %d\n",a[1],a[2]);
    printf("%d %d\n",a[0],a[1]);
    printf("%d %d\n",a[2],a[3]);
}
int main(){
    scanf("%d",&n);
    if (n%4>1) printf("NO\n");
    else{
        printf("YES\n");
        fo(i,1,n/4)
            fo(j,i+1,n/4){
                fo(k,0,3) a[k]=(i-1)*4+k+1;
                fo(k,0,3) b[k]=(j-1)*4+k+1;
                work();
            }
        fo(i,1,n/4){
            fo(k,0,3) a[k]=(i-1)*4+k+1;
            if (n%4==0) solve4();else solve5();
        }
    }
}
阅读更多

Same or not

11-25

nProblem DescriptionnEveryone konws how to traveling a tree using the DFS strategy. But we also know that there are many ways to do so. For example, giving a tree as the following picture, we may get three ways: 010011, 001101, 01010011. 0 stands for the down operation while 1 means the up operation.nNow we make a constraint: if one node has k direct childs, you can visit a node at most 2*k times, if k == 0, you can visit it only once, in the example, the root has two direct child. Like the example, you can only get two ways: 010011, 001101. Because the way 01010011 will visit the node in yellow four times.nHere is the problem: ACboy drawed a tree, but is not very nice, so he won't show you the picture. Instread he will give you two strings indicating that the ways to travel the tree. Of cource, the strings will only contain 0 and 1. And your mission is to tell whether ACboy is telling the truth. For example, he drawed a picture as the following, if he give you 010011 and 001101, then he is telling the truth, but if he give you 010011 and 01010011, you konw that he is telling a lie.nn ![](http://acm.hdu.edu.cn/data/images/C138-1005-1.jpg)nnInputnOn the first line of input is a single positive integer n, telling the number of test scenarios to follow.Each test case consists of two lines, each containing a string of the characters '0' and '1' of length at most 3000, both describing a way to travel the tree.n nnOutputnFor each test case output a line containing the word "True" or the word "False", depending on whether ACboy is telling the truth.n nnSample Inputn2n010011n001101n010011n01010011n nnSample OutputnTruenFalse

没有更多推荐了,返回首页