Codeforces Round #563 (Div. 2) ABCD

传送门

A:签到题

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    int a[4010];
    int main()
    {
    	int n;
    	cin>>n;
    	for(int i=0;i<2*n;i++)
    	{
    		cin>>a[i];
    	}
    	sort(a,a+2*n);
    	int ans1=0,ans2=0;
    	for(int i=0;i<n;i++)
    	{
    		ans1+=a[i];
    	}
    	for(int i=2*n-1;i>=n;i--)
    	{
    		ans2+=a[i];
    	}
    	if(ans1==ans2)
    	{
    		cout<<-1<<endl;
    		return 0; 
    	}
    	for(int i=0;i<2*n;i++)
    	{
    		cout<<a[i]<<" ";
    	}
    	//cout<<ans1<<" "<<ans2<<endl;
    	return 0;
    }

B:给你n个数 你可以进行任意多次操作 当ai+aj是奇的时候 即可交换 让求这些数组组成的数的字典序最小

思路:动手画一画即可知道,将这个数组按照奇偶分开 进行排序 然后分别从这两个数组中取个数 谁小输出谁 有个特例 如果这个数组中只包含奇或者偶的情况的时候 我们没办法进行这中操作 直接输出就行了

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int a[100100];
int b[100100];
int main()
{
	int n;
	cin>>n;
	int add=0,over=0;
	for(int i=0;i<n;i++)
	{
		int x;
		cin>>x;
		if(x%2)
		a[add++]=x;
		else
		b[over++]=x;
	}
	if(add==n)
	{
		for(int i=0;i<n;i++)
		{
			cout<<a[i]<<" ";
		}
		cout<<endl;
		return 0;
	} 
	if(over==n)
	{
		for(int i=0;i<n;i++)
		{
			cout<<b[i]<<" ";
		}
		cout<<endl;
		return 0;
	}
	sort(a,a+add);
	sort(b,b+over);
	int i=0,j=0;
	int flag=0;
	while(i<add&&j<over)
	{
		if(flag)
		{
			cout<<" ";
		}
		if(a[i]<b[j])
		{
			cout<<a[i];
			i++;
		}
		else
		{
			cout<<b[j];
			j++;
		}
		flag++;
	}
	while(i<add)
	{
		if(flag)
		{
			cout<<" ";
		}
		cout<<a[i];
		i++;
		flag++; 
	}
	while(j<over)
	{
		if(flag)
		{
			cout<<" ";
		}
		cout<<b[j];
		j++;
		flag++;
	}
	cout<<endl;
	return 0;
} 

C:给你n个数,下标从2~n 这个数列有以下特征

1.任意两个数 如果他们互质 那么他们的值不能够相等

2.数列中的最大值尽可能的小。

思路:如果这个数为偶数直接赋1 然后如果这个数与前面所有数都互质那直接ans++ 如果和前面部分互质缺为奇数 那我们就把他赋值为他的因子 所在的标记

    #include<cstdio>
    #include<map>
    #include<iostream>
    using namespace std;
    const int N =1e5+10;
    int phi[N], prime[N];
    map<int,int>mp;
    int tot;//tot计数,表示prime[N]中有多少质数 从0开始计数
    void Euler(){
        phi[1]=1;
        for(int i=2;i<N;i++){
            if(!phi[i]){
                phi[i]=i-1;
                prime[tot++]=i;
            }
            for(int j=0;j<tot&&1ll*i*prime[j]<N;j++){
                if(i%prime[j])phi[i*prime[j]]=phi[i]*(prime[j]-1);
                else{
                    phi[i*prime[j]]=phi[i]*prime[j];
                    break;
                }
            }
        }
    }
    int main(){
        Euler();
    	int n;
    	cin>>n;
    	int ans=1;
    	for(int i=2;i<=n;i++)
    	{
    		if(i%2==0)
    		{
    			cout<<1<<" ";
    			mp[i]=1;
    			continue;
    		}
    		if(phi[i]==i-1)
    		{
    			cout<<++ans<<" ";
    			mp[i]=ans;
    			continue;
    		}
    		else
    		{
    			int flag=0;
    			for(int j=3;j*j<=i;j++)
    			{
    				if(i%j==0)
    				{
    					cout<<mp[j]<<" ";
    					mp[i]=mp[j];
    					flag=1;
    					break;
    				}
    			}
    			if(flag==0)
    			{
    				mp[i]=++ans;
    				cout<<mp[i]<<" ";
    			}
    		}
    	}
    	cout<<endl;
    }

D:题意:让你构造一个数列A 使他任何一个子段异或值不能是0 也不能是 x 同时使他最长

这里我们考虑 优先构造一个数列A 的前缀异或和 B数列
那么 A[ i ] = B[ i ] ^ B [ i - 1 ];

我们首先考虑 如果想要尽可能的长同时不出现 0 和 x 那样的话
我们构造数列B 的时候就最好只选取 i ^ x 和 i 中的 仅一个 那样就保证了 我们异或的时候不会出现 x

由于我们 只能选 这异或里面的一半数据 所以 最后 i 最长 是 2^(n-1)

由于 B 里面相邻每位都是不同的 所以自然不会出现 0
 

#include<bits/stdc++.h>
#define ll long long
using namespace std;
vector<ll>v;
bool vis[1<<18];
int main()
{
	ll n,x;
	cin>>n>>x;
	ll len=(1<<n);
	vis[x]=1;
	v.push_back(0);
	for(int i=1;i<len;i++)
	{
		if(vis[i])
		{
			continue;
		}
		vis[i]=vis[i^x]=1;
		v.push_back(i);
	}
	cout<<v.size()-1<<endl;
	for(int i=1;i<v.size();i++)
	{
		cout<<(v[i]^v[i-1])<<" ";
	} 
	cout<<endl;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值