题目链接: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"<