Codeforces Round #669 (Div. 2) (A B C)

A

题意:给出一个只有0和1组成的数组(从a1到an),奇数项加上,偶数项减去。例如110,就是1-1+0。我们可以在数组中去掉 最多n/2个元素,使得数组和为0.

题解:如果所有元素和刚好为0,那么直接输出。否则,需要删除一个元素。

我们将其划分为三段,a*b(a是左边(按题目规则所得的)总和,b是右边总和,*是一个未知元素,0或1)

我们需要找到一个点使得a==b即可。然后去除*,使得整体的总和变成a-b=0.

 (我也忘了为什么当初觉得一定可以找到这个点,不过确实过了,等我想到再补上)

#include<bits/stdc++.h>
using namespace std;
int a[1005],sum[1005];
int main(){
    int t,n;cin>>t;
    while(t--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            if(i&1)sum[i]=sum[i-1]+a[i];
            else sum[i]=sum[i-1]-a[i];
        }
        if(sum[n]==0){
            printf("%d\n",n);
            for(int i=1;i<=n;i++){
                printf("%d ",a[i]);
            }
            printf("\n");
        }
        else for(int i=1;i<=n;i++){
            if(sum[i-1]-(sum[n]-sum[i])==0){
                printf("%d\n",n-1);
                for(int j=1;j<=n;j++){
                    if(j==i) continue;
                    printf("%d ",a[j]);
                }
                printf("\n");
                break;
            }
        }
    }
}

 

B

题解:暴力枚举,先把最大的放第一个,接下来在没有被选中的数里,不断求最大公因数,不断选出使公因数最大的元素。

#include<bits/stdc++.h>
using namespace std;
int a[1005],v[1005];
int cmp(int x,int y){
    return x>y;
}
int gcd(int x,int y){
    return y==0?x:gcd(y,x%y);
}
int main(){
    int t,n;cin>>t;
    while(t--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            v[i]=0;
        }
        sort(a+1,a+1+n,cmp);
        printf("%d ",a[1]);
        v[1]=1;
        int now=a[1],cnt=1;
        while(cnt<n){
            int maxn=0,maxi=0;
            for(int i=1;i<=n;i++){
                if(v[i]) continue;
                int tt=gcd(now,a[i]);
                if(tt>maxn){
                    maxn=tt;
                    maxi=i;
                }
            }
            printf("%d ",a[maxi]);
            now=maxn;
            v[maxi]=1;
            cnt++;
        }
        printf("\n");
    } 
}

 

C

 

题解:假设两个数a,b(其中a>b),我们分别求出a%b=x与b%a=y。很显然,y大于x,且y与b相等。所以我们可以通过两次询问得出一个元素的值。最后还会剩下一个数,只要在前面给其他数做标记就可以把它单独确定出来。(第一次互动题,当时没搞懂怎么加fflush(stdout),原来要在输出换行后加)

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;
int n,a[N],v[N];
//1 0 2 1
int main(){
    scanf("%d",&n);
    queue<int>q;
    for(int i=1;i<=n;i++) {
        q.push(i);
    }
    int x,y;
    while(q.size()>1){
        int i=q.front();q.pop();
        int j=q.front();q.pop();
        printf("? %d %d\n",i,j);
        fflush(stdout);
        scanf("%d",&x);
        printf("? %d %d\n",j,i);
        fflush(stdout);
        scanf("%d",&y);
        if(x<y) {
            a[j]=y;
            v[y]=1;
            q.push(i);
        }
        else {
            a[i]=x;
            v[x]=1;
            q.push(j);
        }
    }
    for(int i=1;i<=n;i++){
        if(!v[i]) {
            a[q.front()]=i;break;
        }
    }
    printf("!");
    for(int i=1;i<=n;i++){
        printf(" %d",a[i]);
    }
        fflush(stdout);
}
View Code

 

posted on 2020-09-09 18:13  学无止境的小程序员  阅读(147)  评论(0编辑  收藏  举报

导航