传送门:CodeforcesRound494Div3
做都做了,还是发一下题解吧。
A. Polycarp’s Pockets
数值相同的数的个数的最大值
#include<bits/stdc++.h>
using namespace std;
int n,a[102],ans,res;
int main(){
int i,j;
scanf("%d",&n);
for(i=1;i<=n;++i) scanf("%d",&a[i]);
sort(a+1,a+n+1);
for(i=1;i<=n;i=j+1){
for(j=i;a[j+1]==a[i] && (j<n);++j);
ans=max(ans,j-i+1);
}
printf("%d",ans);
}
B. Binary String Constructing
随便构造一下,多的放两边。
代码无脑巨丑,不宜观看
#include<bits/stdc++.h>
using namespace std;
int a,b,x,n,ans[102];
int main(){
int i,j;
scanf("%d%d%d",&a,&b,&x);
n=a+b;
if(x%2==0){
if(a==x/2){
for(i=1;i<=x/2;++i) printf("10");
b-=x/2;
for(i=1;i<=b;++i) printf("1");
}else if(b==x/2){
for(i=1;i<=x/2;++i) printf("01");
a-=x/2;
for(i=1;i<=a;++i) printf("0");
}else{
for(i=1;i<=x/2;++i) printf("10");
a-=x/2;b-=x/2;
for(i=1;i<=a;++i) printf("0");
for(i=1;i<=b;++i) printf("1");
}
}else{
if(a==(x+1)/2){
for(i=1;i<=(x+1)/2;++i) printf("01");
b-=(x+1)/2;
for(i=1;i<=b;++i) printf("1");
}else if(b==(x+1)/2){
for(i=1;i<=(x+1)/2;++i) printf("10");
a-=(x+1)/2;
for(i=1;i<=a;++i) printf("0");
}else{
for(i=1;i<=(b-(x+1)/2);++i) printf("1");
for(i=1;i<=(x+1)/2;++i) printf("10");
for(i=1;i<=(a-(x+1)/2);++i) printf("0");
}
}
}
C. Intense Heat
此题暴力可过。
非要作死写二分,细节没处理对还WA…
#include<bits/stdc++.h>
using namespace std;
#define db double
const int N=5050;
const db eps=1e-8;
int n,k;
db a[N],l,r,mid,ans,b[N],c[N],mx=-1.0,mn=5000.0;
inline bool check(db res)
{
int i,j;
b[1]=a[1]-res;c[1]=min(b[1],0.0);
for(i=2;i<=n;++i){b[i]=a[i]-res*i;c[i]=min(c[i-1],min(b[i],0.0));}
for(i=k;i<=n;++i) if(b[i]>=eps+c[i-k]) return true;
return false;
}
int main(){
int i,j;
b[0]=0;a[0]=0.0;
scanf("%d%d",&n,&k);
for(i=1;i<=n;++i){
scanf("%lf",&a[i]);
mn=min(mn,a[i]);
mx=max(mx,a[i]);
a[i]=a[i-1]+a[i];
}
l=mn;r=mx;
if(mn==mx){
printf("%.7lf\n",mn);
return 0;
}
while(r-l>=eps){
mid=(l+r)/2;
if(check(mid)) l=mid;
else r=mid;
}
printf("%.7lf\n",l);
}
D. Coins and Queries
对于每个二进制位数上不为0的位
i
i
,贪心用值小于等于的来替代,没有了就输出-1。
从大到小遍历保证最优。
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,q,bin[33],v[33],tag[33];
int ans,res;
int main(){
int i,j,ix,iy;
bin[0]=1;for(i=1;i<=29;++i) bin[i]=bin[i-1]<<1;
scanf("%d%d",&n,&q);
for(i=1;i<=n;++i){
scanf("%d",&ix);
for(j=0;j<=29;++j){
if(bin[j]==ix) break;
}v[j]++;
}
while(q--){
ans=0;
for(i=0;i<=29;++i) tag[i]=v[i];
scanf("%d",&ix);
for(i=29;i>=0;--i)
if((ix&bin[i]) && tag[i]>0){ix-=bin[i];tag[i]--;ans++;}
for(i=29;i>=0;--i) if(ix&bin[i]){
res=bin[i];
for(j=i-1;j>=0;--j) if(tag[j]>0){
if(res/bin[j]<=tag[j]){
tag[j]-=res/bin[j];
ans+=res/bin[j];
res=0;break;
}else{
ans+=tag[j];
res-=tag[j]*bin[j];
tag[j]=0;
}
}
if(res>0) break;
else ix-=bin[i];
}
if(ix>0) printf("-1\n");
else printf("%d\n",ans);
}
}
E. Tree Constructing
数烷烃是真的有趣。
一开始想直接用等比数列判存在性,结果爆long long不说还WA…
所以当
n≤d
n
≤
d
时,直接输出-1
我们先直接把直径建出来,然后在每个链上的点上长叶子点和链上最远点距离不超过直径的子树,限制一下k就好了。如果所有点都填满了还没凑到n,不就不存在了吗,摔
ps:好多特判啊
#include<bits/stdc++.h>
using namespace std;
const int N=4e5+10;
int n,d,k,pos,lim;
int u[N],v[N],l;
inline void bb(){
printf("NO\n");
exit(0);
}
inline void dfs(int x,int fa,int dep)
{
if(pos>n) return;
u[++l]=x;v[l]=fa;
if(pos==n || dep==lim) return;
for(int i=1;i<k && pos<n;++i){pos++;dfs(pos,x,dep+1);}
}
int main(){
int i,j;
scanf("%d%d%d",&n,&d,&k);
if(k==1){
if(n>2 || d>1) bb();
if(n==2 && d!=1) bb();
if(n==1 && d>0) bb();
printf("YES\n");
if(n==2) printf("1 2");
return 0;
}
if(n<=d) bb();pos=d+1;
for(i=1;i<=d;++i) u[++l]=i,v[l]=i+1;
for(i=2;i<=d && pos<n;++i){
j=max(i-1,d+1-i);
lim=d-j;
for(j=1;j<k-1 && pos<n;++j){pos++;dfs(pos,i,1);}
}
if(pos<n) bb();
printf("YES\n");
for(i=1;i<=l;++i) printf("%d %d\n",u[i],v[i]);
}
F. Abbreviation
又看错题+理解错题意了!!
An abbreviation is a replacement of some segments of words with their first uppercase letters. In order to perform an abbreviation, you have to choose at least two non-intersecting equal segments of words, and replace each chosen segment with the string consisting of first letters of the words in the segment (written in uppercase).
注意at least two和non-intersecting TAT
不然就会像我一样WA而不知所措。
直接dp就好了,这题不难(如果你一遍就看清楚了题的话)。
作死双哈希不解释。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=170437,hh=29;
const int mob=460931,tt=47;
int a[305],b[305];
int ans,sum,n,m,cnt,f[305][305],ss[305];
char s[100020];
int main(){
int i,j,k,pos,res,re;ll rx,ry;
scanf("%d",&n);
for(i=1;i<=n;++i){
scanf("%s",s);
m=strlen(s);
rx=0;ry=0;ss[i]=ss[i-1]+m+1;
for(j=0;j<m;++j){
rx=(rx*hh%mod+s[j]-'a'+1)%mod;
ry=(ry*tt%mob+s[j]-'a'+1)%mob;
}
a[i]=rx;b[i]=ry;
}
for(i=1;i<n;++i)
for(j=i+1;j<=n;++j)
if(a[i]==a[j] && b[i]==b[j]){
if(!f[i-1][j-1]) f[i][j]=1;
else{
int q=min(j-i-1,f[i-1][j-1]);
f[i][j]=q+1;
}
}
ans=ss[n]-1;sum=ss[n]-1;
for(i=1;i<n;++i)
for(j=1;i+j<=n && j<=i;++j){
res=ss[i]-ss[i-j]-j-1;
if(!res) continue;
cnt=1;
for(k=i+j;k<=n;){if(f[i][k]>=j){cnt++;k+=j;}else k++;}
if(cnt>1){
ans=min(ans,sum-res*cnt);
}
}
printf("%d\n",ans);
}