Codeforces Round #494 (Div. 3)
A. Polycarp's Pockets
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
int a[111],ans,n;
int main() {
scanf("%d",&n);
rep(i,1,n){int x;
scanf("%d",&x);
++a[x];
ans=max(ans,a[x]);
}
printf("%d\n",ans);
return 0;
}
B. Binary String Constructing
先用01交替,相邻不同的位置个数为x-1,然后把剩余的01放上去使得答案为x。第一个数可能是1,也可能是0,都要计算
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
int num[2],x,A[555],cc;
int ck(){int ans=0;
rep(i,1,cc-1)if(A[i]!=A[i+1])++ans;
return ans==x;
}
int main() {
scanf("%d%d%d",&num[0],&num[1],&x);
int a=num[0],b=num[1];
A[++cc]=0;
--num[0];
for(int i=1;i<=x-1;++i){
A[++cc]=A[cc-1]^1;
--num[A[cc]];
}
int t=A[cc];
while(num[t])A[++cc]=t,--num[t];
while(num[t^1])A[++cc]=(t^1),--num[t^1];
if(ck()){rep(i,1,cc)printf("%d",A[i]);return puts(""),0;}
cc=0;
num[0]=a;num[1]=b;
A[++cc]=1;
--num[1];
for(int i=1;i<=x-1;++i){
A[++cc]=A[cc-1]^1;
--num[A[cc]];
}
t=A[cc];
while(num[t])A[++cc]=t,--num[t];
while(num[t^1])A[++cc]=(t^1),--num[t^1];
if(ck()){rep(i,1,cc)printf("%d",A[i]);return puts(""),0;}
return 0;
}
C. Intense Heat
推了半天dp,发现是暴力。。。
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define LD long double
using namespace std;
int a[5555],n,k;
LD ans=0;
int main() {
scanf("%d%d",&n,&k);
rep(i,1,n) scanf("%d",&a[i]);
rep(i,2,n) a[i]+=a[i-1];
rep(i,1,n){
rep(j,i+k-1,n){
int sum = a[j]-a[i-1];
ans = max(ans,(LD)sum/(j-i*1.0+1.0));
}
}
printf("%.10f\n",(double)ans);
return 0;
}
D. Coins and Queries
存一下,每种value出现了多少次,从大到小贪心即可
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define LD long double
typedef long long ll;
using namespace std;
int n,A[55],m;
int main() {
scanf("%d%d",&n,&m);
rep(i,1,n) {ll x;int tmp=0;
scanf("%I64d",&x);
while(x)x>>=1LL,++tmp;
++A[tmp-1];
}
rep(ti,1,m){ll x,ans=0;
scanf("%I64d",&x);
for(ll i=35;i>=0;--i){
ll t = (1LL<<i);
ll s = x/t;
ll tmp = s*t;
if(s>A[i])s=A[i];
ans += s;
x-=s*t;
}
printf("%I64d\n",x==0?ans:-1);
}
return 0;
}
E. Tree Constructing
先把一条直径构造出来,从左端开始早每个节点的分出来的树,通过节点的编号确定树高,k的确定分支的个数。构造完check一下是否合法,即是一棵树,且直径符合条件。然后我check直径忘+1了。。再快30s就A了。。。依旧是zz般的手速
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define LD long double
typedef long long ll;
const int N = 4e5 + 7;
using namespace std;
vector<int> G[N][2];
void add(int u,int v){
G[u][0].push_back(v);
G[v][1].push_back(u);
}
int n,d,k;
int cald(int p,int d){
if(d%2==0){
if(p<=d/2)return p-1;
else return d-p;
}
else {
int t = (d+1)/2;
if(p<=t) return p-1;
else return d-p;
}
}
int cnt,sk[N],h[N];
void bfs(int s,int dep){
queue<int> q;
q.push(s);h[s]=0;
while(!q.empty()){
int u=q.front();q.pop();
if(h[u]==dep)continue;
while(sk[u]<k&&cnt<n){
++sk[u];
++cnt;
++sk[cnt];
h[cnt]=h[u]+1;
add(u,cnt);
q.push(cnt);
}
}
}
int vis[N],dis[N];
int ck(){
queue<int> q;
q.push(1);vis[1]=1;dis[1]=1;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<G[u][0].size();++i){
int v=G[u][0][i];
if(vis[v])continue;
vis[v]=1;
dis[v]=dis[u]+1;
q.push(v);
}
for(int i=0;i<G[u][1].size();++i){
int v=G[u][1][i];
if(vis[v])continue;
vis[v]=1;
dis[v]=dis[u]+1;
q.push(v);
}
}
rep(i,1,n)if(!vis[i])return 0;
int idx=1;
rep(i,2,n){
if(dis[idx]<dis[i])idx=i;
}
q.push(idx);
dis[idx]=1;memset(vis,0,sizeof(vis));
vis[idx]=1;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<G[u][0].size();++i){
int v=G[u][0][i];
if(vis[v])continue;
vis[v]=1;
dis[v]=dis[u]+1;
q.push(v);
}
for(int i=0;i<G[u][1].size();++i){
int v=G[u][1][i];
if(vis[v])continue;
vis[v]=1;
dis[v]=dis[u]+1;
q.push(v);
}
}
idx=1;
rep(i,2,n){
if(dis[idx]<dis[i])idx=i;
}
return dis[idx]==d;
}
int main() {
scanf("%d%d%d",&n,&d,&k);
d++;
cnt = d;
for(int i=2;i<=d;++i){
add(i-1,i);
if(i<d){
int dep = cald(i,d);
sk[i]=2;
bfs(i,dep);
}
}
if(ck()){
puts("YES");
rep(i,1,n){
for(int j=0;j<G[i][0].size();++j)printf("%d %d\n",i,G[i][0][j]);
}
}
else puts("NO");
return 0;
}