这把状态奇差,可能是因为令人崩溃的蚊子数量……做完D就快没时间了,E又坑多
A 瞎搞
http://codeforces.com/contest/1003/problem/A
#include<bits/stdc++.h>
using namespace std;
int a[100];
int mm;
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
int x;
scanf("%d",&x);
a[x]++;
mm=max(mm,a[x]);
}
printf("%d",mm);
}
B 瞎搞(出奇的烦)
#include<bits/stdc++.h>
using namespace std;
int s[202];
int main()
{
int a,b,x;
scanf("%d%d%d",&a,&b,&x);
int aa=a,bb=b;
if(x%2==1)
{
a-=(x-1)/2;
b-=(x-1)/2;
int c=(x-1)/2;
int j=0;
while(a--)
{
s[j++]=0;
//printf("s %d %d\n",j-1,s[j-1]);
}
while(b--)
{
s[j++]=1;
//printf("s'' %d %d\n",j-1,s[j-1]);
}
while(c--)
{
s[j++]=0;
s[j++]=1;
}
}
else
{
if(a>b)
{
int c=x/2;int d=x/2-1;
a-=c;
b-=d;
int j=0;
while(a--)
{
s[j++]=0;
}
while(b--)
{
s[j++]=1;
}
s[j++]=0;
while(d--)
{
s[j++]=1;
s[j++]=0;
}
}
else
{
int c=x/2;int d=x/2-1;
a-=d;
b-=c;
int j=0;
while(b--)
{
s[j++]=1;
}
while(a--)
{
s[j++]=0;
}
s[j++]=1;
while(d--)
{
s[j++]=0;
s[j++]=1;
}
}
}
// printf("yrs,%d %d\n",s[0],s[2]);
// printf("%d\n",a+b);
for(int i=0;i<aa+bb;i++)
{
cout<<s[i];
}
}
C 暴力(数据量估算一下,优化好暴力可以过,这题一个小错卡了好久)
#include<bits/stdc++.h>
using namespace std;
int a[5005],bs[5005],su;
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
su+=a[i];
bs[i]=su;
// printf("%d ",bs[i]);
}
double mmm=0;
for(int i=k;i<=n;i++)
{
int nm=bs[i],mm=bs[i];
for(int r=1;r<=n-i;r++)
{
// printf("r %d\n",r);
nm+=a[i+r];
nm-=a[r];
mm=max(mm,nm);
}
double c=mm*(double)1.0/i;
mmm=max(mmm,c);
}
// printf("%.10lf",mmm);
cout<<setprecision(15)<<mmm;
}
D 贪心
题目基本明说了跟二进制表示有关,可以证明必须优先满足大的二进制位,如果没有对应硬币就往下推,用栈存二进制位,大的后进先出。
#include<bits/stdc++.h>
using namespace std;
int a[32];
int main()
{
int n,q;
scanf("%d%d",&n,&q);
for(int i=0;i<n;i++)
{
int x;
scanf("%d",&x);
int j=0;
x/=2;
while(x)
{
x/=2;
j++;
}
a[j]++;
}
int b[32];
for(int j=0;j<q;j++)
{
for(int i=0;i<32;i++){
b[i]=a[i];
// printf("i %d bi %d ",i,b[i]);
}
int x;
int ans=0;
int flg=0;
scanf("%d",&x);
stack<int> qq;
int k=0;
while(x)
{
if(x&1)qq.push(k);
k++;
x>>=1;
}
// printf("sz %d\n",qq.size());
while(!qq.empty())
{
int c=qq.top();
// printf("c:%d\n",c);
qq.pop();
int k=c;
int scale=1;
while(scale)
{
//printf("k %d b[k] %d scale %d\n",k,b[k],scale);
if(b[k]>=scale)
{
// printf("b k %d-=scale %d",k,scale);
b[k]-=scale;
ans+=scale;
scale=0;
}
else{
//b[k]=0;
// printf("scale %d k %d\n",scale,k);
scale-=b[k];
ans+=b[k];
b[k]=0;
scale*=2;
k--;
}
if(k<0)break;
}
if(scale){
flg=1;
//break;
}
}
if(flg==1)printf("-1\n");
else printf("%d\n",ans);
}
}
E 建树
大坑1 :d(半径)是最长路径长度,不是你搜索时树的深度
大坑2: k可以为1(这个被卡到爆炸)
先构造一条路径,从两边向中间添加树枝,应该是中间可以加最深的树,每个都深搜一遍,如果到了n就结束,最后没到n就NO。
#include<bits/stdc++.h>
using namespace std;
int n,d,k;
#define N 400005
int doo[N],maxdep[N];
int nown;
vector<int> eg[N];
void dfs(int dep,int rt,int mdep)
{
// printf("dfs %d depth %d\n",rt,dep);
if(dep>mdep)return;
if(nown==n)return;
while(doo[rt]<k)
{
nown++;
eg[nown].push_back(rt);
doo[nown]++;
doo[rt]++;
dfs(dep+1,nown,mdep);
if(nown==n)break;
}
return;
}
int main()
{
scanf("%d%d%d",&n,&d,&k);
doo[1]++;doo[d+1]++;
if(d+1>n)
{
printf("NO");
return 0;
}
//eg[1].push_back(2);
eg[d+1].push_back(d);//从后向前表示
for(int i=2;i<=d;i++)
{
eg[i].push_back(i-1);
//eg[i].push_back(i+1);
doo[i]+=2;
if(doo[i]>k)
{
printf("NO");
return 0;
}
maxdep[i]=min(i-1,d+1-i);
//printf("maxdep %d is %d\n",i,maxdep[i]);
}
nown=d+1;
for(int i=2;i<=d;i++)
{
if(nown==n)break;
dfs(1,i,maxdep[i]);
}
if(nown<n)
{
printf("NO");
return 0;
}
else
{
printf("YES\n");
for(int i=1;i<=nown;i++)
{
if(eg[i].size()>0)
printf("%d %d\n",i,eg[i][0]);
}
}
}