Codeforces1079
A.Kitchen Utensils
代码:
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; const int MAXN=100+2; const int MAXK=100+2; int a[MAXN],c[MAXK],N,K,C,M,Ans; int main(){ cin >> N >> K; for(int i=1;i<=N;i++){ cin >> a[i]; c[a[i]]++,C=max(c[a[i]],C); } M=C/K; if(C%K) M++; sort(a+1,a+N+1); for(int i=1;i<=N;i++){ Ans+=M*K-c[a[i]]; while(a[i+1]==a[i]) i++; } cout << Ans << endl; return 0; }
B.Personalized Cup
代码:
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; const int MAXL=200+2; int a,b,r; char S[MAXL]; bool Flag; int main(){ scanf("%s",S+1); for(a=1;a<=5;a++){ for(b=1;b<=20;b++){ r=a*b-strlen(S+1); if(r>=0){ Flag=1; break; } } if(Flag) break; } cout << a << " " << b << endl; for(int i=1,j=1,k,c=1;i<=a;i++){ for(k=1;k<=r/a;k++) cout << "*"; if(c<=r%a) c++,k++,cout << "*"; while(k<=b) cout << S[j++],k++; cout << endl; } return 0; }
C.Playing Piano
题意:给定一个序列a,求一个由1~5构成的数列b,满足:b[i]<b[i-1] if a[i]<a[i-1];b[i]>b[i-1] if a[i]>a[i-1];b[i]!=b[i-1] if a[i]==a[i-]1
题解:假如没有第三个条件的话可以贪心,但是有了第三个条件,连续的相等的数应该怎么取就会对后面的产生影响,这时候考虑DP:令f[i][j]表示第i个位置放j是否有解,状态转移显然,DP的时候注意记录一下当前状态可以从哪个状态转移过来。
代码:
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; const int MAXN=100000+2; const int MAXK=5+2; int N,a[MAXN],g[MAXN][MAXK],Ans[MAXN]; bool f[MAXN][MAXK],Flag; bool Check(int x,int y,int s,int t){ if(a[x]<a[y] && s<t) return 1; if(a[x]>a[y] && s>t) return 1; if(a[x]==a[y] && s!=t) return 1; return 0; } int main(){ cin >> N; for(int i=1;i<=N;i++) scanf("%d",a+i); for(int i=1;i<=5;i++) f[1][i]=1; for(int i=2;i<=N;i++) for(int j=1;j<=5;j++) for(int k=1;k<=5;k++) if(f[i-1][k] && Check(i-1,i,k,j)){ f[i][j]=1,g[i][j]=k; break; } for(int i=1;i<=5;i++) if(f[N][i]){ for(int j=N,k=i;j;k=g[j][k],j--) Ans[j]=k; Flag=1; break; } if(Flag) for(int i=1;i<=N;i++) cout << Ans[i] << " "; else cout << -1; cout << endl; return 0; }
D.Barcelonian Distance
题意:给定一个曼哈顿图和图上的一条直线,求可以经过该直线的两点之间的最短距离
题解:作垂线,找出四个交点来,然后取距离最小值。
代码:
#include <cmath> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; #define exp 1e-8 double a,b,c,X1,Y1,X2,Y2,x[5],y[5],Ans; double dis(double x1,double y1,double x2,double y2){ return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));} int main(){ cin >> a >> b >> c >> X1 >> Y1 >> X2 >> Y2; x[1]=X1,y[1]=(-a*X1-c)/b; x[2]=(-b*Y1-c)/a,y[2]=Y1; x[3]=X2,y[3]=(-a*X2-c)/b; x[4]=(-b*Y2-c)/a,y[4]=Y2; Ans=fabs(X1-X2)+fabs(Y1-Y2); Ans=min(Ans,fabs(y[1]-Y1)+fabs(Y2-y[3])+dis(x[1],y[1],x[3],y[3])); Ans=min(Ans,fabs(y[1]-Y1)+fabs(X2-x[4])+dis(x[1],y[1],x[4],y[4])); Ans=min(Ans,fabs(X1-x[2])+fabs(Y2-y[3])+dis(x[2],y[2],x[3],y[3])); Ans=min(Ans,fabs(X1-x[2])+fabs(X2-x[4])+dis(x[2],y[2],x[4],y[4])); printf("%.10lf\n",Ans); return 0; }
E.The Unbearable Lightness of Weights
题意:给定一个数,找出n个相同的数a,使得na被唯一表出,求n的最大值
题解:多重背包统计方案数
代码:
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; const int MAXN=100+2; const int MAXA=100+2; int N,W,C,a[MAXN],f[MAXN][MAXN*MAXA],c[MAXA],Ans; int main(){ cin >> N; for(int i=1,t;i<=N;i++){ cin >> t; c[t]++,W+=t,C=max(C,c[t]); } if(N<=2){ cout << N << endl; return 0; } N=0; for(int i=1;i<=100;i++) if(c[i]) a[++N]=i,c[N]=c[i]; f[0][0]=1; for(int i=1;i<=N;i++) for(int j=W;j;j--) for(int k=1;k<=C;k++) for(int t=1;t<=k && t<=c[i] && j>=t*a[i];t++) f[k][j]+=f[k-t][j-t*a[i]]; for(int i=1;i<=N;i++) for(int j=1;j<=c[i];j++) if(f[j][j*a[i]]==1) Ans=max(Ans,j); cout << Ans << endl; return 0; }
F.Vasya and Maximum Matching
(待补)
G.Chattering
(待补)