Codeforces Round #768 (Div. 2)

C. And Matching

题意:给出n和k,要求将0到n-1的数两两配对,其与运算之和为k。保证n为2的幂。

解:怎么简单怎么来。显然 i 与 n-i-1 与之和为0。现在留出k,那么要给n-k-1找对象(?,使得它们与出来是0。0显然满足这个要求。现在留下n-1和k,n-1和k与完还是k,完美。考虑到k=n-1时不能这么干,那多拉两个和它们配对,最终在只要对称即可。n-1和n-2可以整出k-1,现在留下0和1要整出1,不够,那拉上n-3和2。n-3的末尾显然是1,问题解决。这样需要6个数,也就是n=4,k=3时无解,特判即可。

代码:

Codeforces Round #768 (Div. 2)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define maxx 45
#define eps 0.00000001
#define inf 0x7fffffff
#define mod 998244353
//#define int long long
int n,k;
int vis[70005];
signed main() {
    int T;
    scanf("%d",&T);
    while(T--){
        for(int i=0;i<n;i++)
            vis[i]=0;
        scanf("%d%d",&n,&k);
        if(n==4){
            if(k==0)
                printf("0 3\n1 2\n");
            else if(k==1)
                printf("1 3\n0 2\n");
            else if(k==2)
                printf("0 1\n2 3\n");
            else if(k==3)
                printf("-1\n");
            continue;
        }
        if(k==0){
            for(int i=0;i<n/2;i++)
                printf("%d %d\n",i,n-1-i);
            continue;
        }
        if(k==n-1){
            printf("%d %d\n",n-1,n-2);
            printf("%d %d\n",1,n-3);
            printf("2 0\n");
            for(int i=3;i<n/2;i++)
                printf("%d %d\n",i,n-i-1);
            continue;
        }
        printf("%d %d\n",k,n-1);
        printf("%d %d\n",n-k-1,0);
        for(int i=1;i<n/2;i++){
            if(i==k||n-i-1==k)
                continue;
            printf("%d %d\n",i,n-i-1);
        }
    }
    return 0;
}
View Code

---TBC---

上一篇:最小生成树-Kruskal(C++)


下一篇:清北学堂Day 6之STL