Codeforces Round #494 (Div. 3) (ABCDE) 题解

题目链接:http://codeforces.com/contest/1003

A题题意:给定N个值,每个集合只能放不相同的数,问把所有值放进去最少需要多少个集合。

A题题解:直接暴力统计最多出现的数的次数即可。

AC代码:

#include 
using namespace std;
#define _for(i,a,b) for(int i=a;i<=b;i++)
const int maxn = 1e5+7;
int a[105];
int n;
int main(int argc, char const *argv[])
{
	cin>>n;
	int ans = 0;
	_for(i,1,n)
	{
		int x;
		cin>>x;
		a[x]++;
		ans=max(ans,a[x]);
	}
	cout<

B题题意:给定a,b,x三个数,构造一个长度为a+b的数列,其中0的个数等于a,1的个数等于b,a[i]!=a[i+1]的个数等于x。

B题题解:对x分奇偶分情况讨论,然后在两边将多余的01输出即可。

AC代码:

/*
* @Author: 王文宇
* @Date:   2018-07-03 22:40:50
* @Last Modified by:   王文宇
* @Last Modified time: 2018-07-03 23:04:11
*/
#include 
using namespace std;
#define _for(i,a,b) for(int i=a;i<=b;i++)
const int maxn = 1007;
char s[maxn];
int a,b,x;
int main(int argc, char const *argv[])
{
	cin>>a>>b>>x;
	int now = 1;
	int l = x;
	if(x&1)
	{
		if(a>b)
		{
			while(x>1)
			{
				a--;
				b--;
				x-=2;
			}
			while(a--)cout<<0;
			while(l>1)
			{
				cout<<"10";
				l-=2;
			}
			while(b--)cout<<1;
			cout<1)
			{
				a--;
				b--;
				x-=2;
			}
			while(b--)cout<<1;
			while(l>1)
			{
				cout<<"01";
				l-=2;
			}
			while(a--)cout<<0;
			cout<b)
		{
			a-=x/2;
			b-=x/2;
			while(a>1)
			{
				cout<<"0";
				a--;
			}
			while(x>0)
			{
				cout<<"01";
				x-=2;
			}
			while(b--)cout<<"1";
			cout<<0<1)
			{
				cout<<"1";
				b--;
			}
			while(x>0)
			{
				cout<<"10";
				x-=2;
			}
			while(a--)cout<<"0";		
			cout<<1<

C题题意:给定N个数值和K,求一个长度不小于K的子序列,使其平均值最大。

C题题解:因为n<=5000,所以n^2暴力即可。

AC代码:

/*
* @Author: 王文宇
* @Date:   2018-07-03 23:11:04
* @Last Modified by:   王文宇
* @Last Modified time: 2018-07-03 23:19:36
*/
#include 
using namespace std;
#define _for(i,a,b) for(int i=a;i<=b;i++)
const int maxn = 5005;
int n,k;
double ans;
int a[maxn];
int sum[maxn];
int main(int argc, char const *argv[])
{
	cin>>n>>k;
	_for(i,1,n)
	{
		cin>>a[i];
		sum[i]=sum[i-1]+a[i];
	}
	_for(i,0,n-k)
	{
		_for(j,i+k,n)
		{
			int h = sum[j]-sum[i];
			double now = (double)h/(double)(j-i);
			ans = max(now,ans);
		}
	}
	printf("%.15lf\n",ans);
	return 0;
}

D题题意:给定一个只包含2的倍数的数组,然后给定Q个询问,对于每次询问的整数找到取最少的数组中的数的和等于被询问数,无法构成输出-1

D题题解:将给定的数拆成2进制统计每个进制然后对于每个询问暴力即可。

AC代码:

/*
* @Author: 王文宇
* @Date:   2018-07-03 23:47:28
* @Last Modified by:   王文宇
* @Last Modified time: 2018-07-04 00:49:17
*/
#include 
using namespace std;
#define _for(i,a,b) for(int i=a;i<=b;i++)
const int maxn = 2e5+7;
int n,q;
int a[maxn],num[maxn];
int main(int argc, char const *argv[])
{
	cin>>n>>q;
	_for(i,1,n)
	{
		cin>>a[i];
		int k = -1;
		while(a[i])
		{
			k++;
			a[i]/=2;
		}
		num[k]++;
	}
	_for(i,1,q)
	{
		int x;
		cin>>x;
		int ss = 0;
		int now = 0;
		int ok = 0;
		long long k = 1;	
		long long next = (long long)x;
		while(k<=next)
		{
			k*=2;
			now++;
		}
		while(next>0)
		{
			k/=2;
			//cout<next)continue;
			if(num[now]*k>=next)
			{
				int h = next/k;
				next-=k*h;
				ss+=h;
			}
			else
			{
				ss+=num[now];
				next-=num[now]*k;
			}
			if(now==-1)
			{
				ok = 1;
				break;
			}	
		}
		if(ok||next<0)cout<<"-1"<

E题题意:给定n,d,k,构造一棵无向树,结点个数为n,直径为d,每个结点的深度不大于k。

E题题解:首先特判不存在的情况,然后先构造出直径,然后在直径上尽可能的加边即可。最后判断加的边是不是等于n-1即可。

AC代码:

/*
* @Author: 王文宇
* @Date:   2018-07-03 23:34:42
* @Last Modified by:   王文宇
* @Last Modified time: 2018-07-04 04:02:26
*/
#include 
using namespace std;
#define _for(i,a,b) for(int i=a;i<=b;i++)
const int maxn = 4e5+7;
int n,d,k,now;
vector > Q;
vector E[maxn];
void dfs(int x,int y,int z)
{
	if(z==y)return;
	for(int i=0;i>n>>d>>k;
	if(n<(d+1))
	{
		cout<<"NO"<


你可能感兴趣的:(贪心,OJ系列-codeforces,构造,模拟)