【比赛链接】:click here~~
这套题是暑假打多校的时候拉的一次比赛,感觉题目都很有意思,所以重新拉出来总结一下。
ZOJ 3549 Little Keng
【题意】:Calculate how many 0s at the end of the value below: 1n + 2n + 3n + ... + mn
【思路】:数据不大直接暴力求解。
代码:
/* * Problem: ZOJ No.3549 * Running time: 0MS * Complier: G++ * Author: herongwei * Create Time: 16:25 2015/9/24 星期四 */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; const int MOD=1e9; LL m,n; LL poww_mod(LL a,LL b){ LL res=a,ans=1; while(b){ if(b&1) ans=res*ans%MOD; b>>=1; res=res*res%MOD; } return ans; } int main(){ while(cin>>m>>n){ LL sum=0; for(int i=1; i<=m; ++i){ sum+=poww_mod(i,n)%MOD; } int jj=0; while(sum>0){ if(sum%10==0) jj++; else break; sum/=10; } cout<<jj<<endl; } return 0; }
【题意】:给一个组合体:由一个圆柱和一个圆台组成,当体积一定V时,求组合体表面积的最小值
【思路】看到题,立刻想到是一些常量肯定成某种比例的时候表面积最小,于是推关系,,推关系,,推了大半天,隐隐约约有一种 关系,但是不确定
突然立刻想到二次函数,可以用三分解决,于是三分三分,无限的三分开始了,此题比较麻烦在于先三分上下体积,然后在体积里在三分上下半径,总的来说就是三分无极限
PS:eps写错了,T了一下下午了,,囧~~
代码:
/* * Problem: ZOJ No.3550 * Running time: 1200MS * Complier: G++ * Author: javaherongwei * Create Time: 8:52 2015/9/23 */ #include <math.h> #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; const double eps=1e-5; // 错写成-1e5,T了一下午 const double pi= acos(-1.0); double R,r,V,v1,v2,H,h,L,ans; int spj(double x){ return (x>eps)-(x<-eps); } double calc(double x){ // the final area r=x; H=v1/(pi*R*R); h=3*v2/(pi*r*r+pi*r*R+pi*R*R); L=sqrt((R-r)*(R-r)+h*h); ans=pi*r*r+2*pi*R*H+pi*L*(R+r); return ans; } double rad(double x){ // after volum and san fen radius v1=x,v2=V-x; double ll=0,rr=R; while(spj(rr-ll)>0){ double mid=ll+(rr-ll)/3; double midd=ll+2*(rr-ll)/3; double midx=calc(mid); double midy=calc(midd); if(midx<midy) rr=midd; else ll=mid; } return calc(ll); } double vv(double x){ //after the result san fen volum R=x; double ll=0,rr=V; while(spj(rr-ll)>0){ double mid=ll+(rr-ll)/3; double midd=ll+2*(rr-ll)/3; double midx=rad(mid); double midy=rad(midd); if(midx<midy) rr=midd; else ll=mid; } return rad(ll); } double solve(){ // san fen the result double ll=0,rr=10*V; while(spj(rr-ll)>0){ double mid=ll+(rr-ll)/3; double midd=ll+2*(rr-ll)/3; double midx=vv(mid); double midy=vv(midd); if(midx<midy) rr=midd; else ll=mid; } return vv(ll); } int main(){ while(scanf("%lf",&V)!=EOF){ printf("%.6f\n",solve()); } return 0; }
【题意】:
/* * Problem: ZOJ No.3551 * Running time: 50MS * Complier: G++ * Author: herongwei * Create Time: 16:25 2015/9/24 星期四 */ #include <math.h> #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; const double eps=1e-5; const double pi= acos(-1.0); const int N = 1e5+10; double dp[N]; int main() { int t,n;double p;scanf("%d",&t); while(t--){ scanf("%d%lf",&n,&p); double ans=0.0; for(int i=1; i<n; ++i){ ans+=1.0*n*(n-1)/(2*p*(n-i)*i); } printf("%.3f\n",ans); } return 0; }
/****************** *dp[i]表示从i个吸血鬼到n个吸血鬼的天数期望 ******************/ #include <math.h> #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; const int N= 1e5+10; double dp[N]; int main(){ int t,n;double p;scanf("%d",&t); while(t--){ scanf("%d%lf",&n,&p); dp[n] = 0; for(int i=n-1; i>=1; i--){ double s1,s2,p1; s1 = (double)n*(n-1)/2; ///从n个人中选两个人出来的选法,也就是C(n,2) s2 = (double)i*(n-i); ///i为从i个人中选出一人的方法,n-i为从吸血鬼中选出一个吸血鬼的总数,共有这么多种 p1 = s2/s1*p; ///人与吸血鬼相遇的概率 dp[i]=(dp[i+1]*p1+1)/p1; } printf("%.3f\n",dp[1]); } return 0; }
/* * Problem: ZOJ No.3554 * Running time: 810MS * Complier: G++ * Author: herongwei * Create Time: 16:25 2015/9/24 星期四 */ #include <math.h> #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; const double eps=1e-5; const double pi= acos(-1.0); const int N = 120; const int M=120+10; int a[M],b[M],c[M]; bool dp[M][M][M]; bool vis[M][M][M]; int main() { int t; while(~scanf("%d",&t)){ memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); memset(vis,0,sizeof(vis)); memset(dp,0,sizeof(dp)); vis[0][0][0]=1; for(int i=0; i<t; ++i){ scanf("%d%d%d",&a[i],&b[i],&c[i]); } if(t<3){ puts("NO"); continue; } for(int f=0; f<t; ++f){ for(int i=0; i<=N; ++i) for(int j=0; j<=N; ++j) for(int k=0; k<=N; ++k) if(vis[i][j][k]){ if(i+a[f]<=N) dp[i+a[f]][j][k]=1; if(j+b[f]<=N) dp[i][j+b[f]][k]=1; if(k+c[f]<=N) dp[i][j][k+c[f]]=1; } memcpy(vis,dp,sizeof(vis)); memset(dp,0,sizeof(dp)); } int ans=-1; for(int i=1; i<=N; ++i){///直接反过来想,枚举所有的可能不大于120的值,只要有满足条件的,就可以 if(vis[i][i][i]==1){ ans=i; break; } } if(ans!=-1){ printf("%d\n",ans); } else puts("NO"); } return 0; }
/* * Problem: ZOJ No.3556 * Running time: 0MS * Complier: G++ * Author: herongwei * Create Time: 16:25 2015/9/24 星期四 */ #include <math.h> #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; const double eps=1e-5; const double pi= acos(-1.0); const int N = 120; const int M=120+10; const int MOD=1e9+7; LL n,k; LL poww(LL a,LL b) { LL res=a,ans=1; while(b) { if(b&1) ans=res*ans%MOD; res=res*res%MOD; b>>=1; } return ans; } int main() { while(~scanf("%lld %lld",&n,&k)) { printf("%lld\n",poww(poww(2,k)-1,n)%MOD); } }
/* * Problem: ZOJ No.3557 * Running time: 0MS * Complier: G++ * Author: herongwei * Create Time: 16:25 2015/9/24 星期四 */ #include <math.h> #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; const double eps=1e-5; const double pi= acos(-1.0); LL n,m,p; LL poww(LL a,LL b){ LL res=a,ans=1; while(b){ if(b&1) ans=res*ans%p; res=res*res%p; b>>=1; } return ans; } LL C(LL a, LL b,LL p){ if(a<b) return 0; if(b>a-b) b=a-b; LL up=1,down=1; for(int i=0; i<b; ++i){ up=up*(a-i)%p; down=down*(i+1)%p; } return up*poww(down,p-2)%p; } LL lucas(LL a,LL b,LL p){ if(b==0) return 1; return C(a%p,b%p,p)*lucas(a/p,b/p,p)%p; } int main(){ while(~scanf("%lld %lld %lld",&n,&m,&p)){ if(n&1){ if(m>(n/2+1)) puts("0"); else printf("%lld\n",lucas(n-m+1,m,p)); } else{ if(m>(n/2)) puts("0"); else printf("%lld\n",lucas(n-m+1,m,p)); } } return 0; }