Codeforces Round #669 (Div. 2)A-C题解

A. Ahahahahahahahaha

题目:http://codeforces.com/contest/1407/problem/A

题解:最多进行n/2的操作次数,我们统计这n个数中1的个数,是否过半,如果没有代表0过半,因此输出剩余的0的个数即可

如果1的个数过半,则考虑1的个数是奇数还是偶数,若为奇数,则再减去一个输出;若为偶数个,则直接输出。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

int main()
{
    int t,n,i,j;
    cin>>t;
    while(t--)
    {
        cin>>n;
        int num=0;
        for(i=1;i<=n;i++)
        {
            int x;
            cin>>x;
            if(x==1)
                num++;
        }
        if(num<=n/2)
        {
            cout<<n/2<<endl;
            for(int j=1;j<=n/2;j++)
                cout<<"0"<<" ";
            cout<<endl;
        }
        else
        {
            if(num%2==0)
            {
                cout<<num<<endl;
                for(int j=1;j<=num;j++)
                    cout<<"1"<<" ";
                cout<<endl;
            }
            else
            {
                cout<<num-1<<endl;
                for(int j=1;j<=num-1;j++)
                    cout<<"1"<<" ";
                cout<<endl;
            }
        }
    }
    return 0;
}

B. Big Vova

题目:http://codeforces.com/contest/1407/problem/B

题解:首先挑选出最大的作为第一个,将其与第一个数互换位置,然后开始从第二位一直到第n位,遍历求出当前最大的gcd,并记录相应的下标,然后和第二到第n位交换位置,最多执行n-1次。

最后输出数组即可。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

int t,n,a[1100];
int gcd(int a,int b)
{
    return b==0?a:gcd(b,a%b);
}

int main()
{
    int i,j,maxn;
    cin>>t;
    while(t--)
    {
        cin>>n;
        int f;
        int maxn=-1;
        for(i=0;i<n;i++)
        {
            cin>>a[i];
            if(a[i]>maxn)
            {
                maxn=a[i];
                f=i;
            }
        }
        swap(a[f],a[0]);
        int cnt=1;
        while(cnt<n)
        {
            int maxgcd=-1;
            int p;
            for(i=cnt;i<n;i++)
            {
                if(gcd(maxn,a[i])>maxgcd)
                {
                    maxgcd=gcd(maxn,a[i]);
                    p=i;
                }
            }
            swap(a[cnt],a[p]);
            maxn=maxgcd;
            cnt++;
        }
        for(i=0;i<n;i++)
            cout<<a[i]<<" ";
        cout<<endl;
    }
    return 0;
}

C. Chocolate Bunny

题目:http://codeforces.com/contest/1407/problem/C

题解:这是一道交互题,以前没碰到过,也好理解。

可以询问 2×n2×n 次,每次给出两个不同的索引 i 和 j,会返回 ai%aj的值。

询问i和j,假设ai>aj,那结果为ai%aj=x<aj

再询问j和i,结果为aj%ai=y=aj

因此aj=y;并将y这个值用map标记,mp[y]=1

反之,若ai<aj,询问i和j,结果为ai%aj=x=ai

再询问j和i,结果为aj%ai=y<ai

因此ai=x,并将x用map标记,mp[x]=1;

最后遍历完整个数组后,还剩下一个,遍历数组找到mp还未标记的那个数,即为最终的a[f]的值

最后输出数组即可。

代码:

#include<bits/stdc++.h>
using namespace std;

const int N=10100;
int x,y,n;
int a[N];
map<int,int>mp;
int main()
{
    int i,j;
    cin>>n;
    int f=1;
    for(i=2;i<=n;i++)
    {
        cout<<"? "<<f<<" "<<i<<endl;
        cin>>x;
        cout<<"? "<<i<<" "<<f<<endl;
        cin>>y;
        if(x>y)
        {
            a[f]=x;
            mp[x]=1;
            f=i;
        }
        else
        {
            a[i]=y;
            mp[y]=1;
        }
    }
    for(i=1;i<=n;i++)
    {
        if(mp[i]==1)
            continue;
        a[f]=i;
        break;
    }
    cout<<"!";
    for(i=1;i<=n;i++)
        cout<<" "<<a[i];
    return 0;
}
原文地址:https://www.cnblogs.com/xiaofengzai/p/13637429.html