【题解】BUPT 2015 freshman contest 2
2016-02-04 00:56
357 查看
A题裸的求最大连续字串和,我的做法是先求一个前缀和,然后我要求的就是所有s[j]-min(s[i]) i<j,最大的值,然后我可以o(1)的维护min(s[i]),这个算法就是o(n)的了
C题的话,因为要找一个矩阵内放一个多米诺骨牌的方案,所以对于每个格子,都有上下左右四中方案,我们利用前缀和的思想,用s[i][j][k]代表以(1,1)为左上角,(i,j)为右下角方向为k的方案数,k=0->3,分别代表上下左右其中一个方向,那么对于选定矩阵,我们可以很容易统计出它如果没有边沿限制的话放一个多米诺骨牌的方案数,上边沿不能向上放,左边沿不能往左放以此类推,把这些减去,剩下方案的除以2 就是答案
long long 判一下
F题是本次的防AK题,其实也什么难度。。只是比较绕,具体题解
传送门:http://blog.csdn.net/pro_space/article/details/50603622
祝大家训练愉快~
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> using namespace std; int s[200100]; int ans; int main() { int t,ci,ansl,ansr,k,n,x; scanf("%d",&t); for (int ci=1;ci<=t;ci++) { memset(s,0,sizeof(s)); scanf("%d",&n); scanf("%d",&s[1]); ans=s[1]; ansl=1; ansr=1; if (s[1]<0) k=1; else k=0; for(int i=2;i<=n;i++) { scanf("%d",&x); s[i]=s[i-1]+x; if (s[i]-s[k]>ans) {ans=s[i]-s[k];ansl=k+1;ansr=i;} if (s[i]<s[k]) k=i; } printf("Case %d:\n",ci); printf("%d %d %d",ans,ansl,ansr); if (ci!=t) printf("\n\n"); else printf("\n"); } return 0; }B 题目因为说了可以每次取任意比例(比利),所以就直接按照J[i]/f[i] 从大到小选就行。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<cstdlib> using namespace std; struct recc { int x,y; }rec[200100]; int cmp(recc a,recc b) { return ((double)a.x/a.y)>((double)b.x/b.y); } int main() { int n,m; double ans=0; while (scanf("%d%d",&m,&n)) { ans=0; memset(rec,0,sizeof(rec)); if (m==-1&&n==-1) return 0; for (int i=1;i<=n;i++) scanf("%d%d",&rec[i].x,&rec[i].y);
sort(rec+1,rec+n+1,cmp); for (int i=1;i<=n,m!=0;i++) { if (m>=rec[i].y) ans+=rec[i].x; else ans+=(double)(m)/rec[i].y*rec[i].x; m=m-min(m,rec[i].y); } printf("%.3lf\n",ans); } return 0; }
C题的话,因为要找一个矩阵内放一个多米诺骨牌的方案,所以对于每个格子,都有上下左右四中方案,我们利用前缀和的思想,用s[i][j][k]代表以(1,1)为左上角,(i,j)为右下角方向为k的方案数,k=0->3,分别代表上下左右其中一个方向,那么对于选定矩阵,我们可以很容易统计出它如果没有边沿限制的话放一个多米诺骨牌的方案数,上边沿不能向上放,左边沿不能往左放以此类推,把这些减去,剩下方案的除以2 就是答案
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> using namespace std; long long sum[510][510][4]; char s[510][510]; int main() { memset(s,0,sizeof(s)); int h,w,l,t,r,b,q; long long ans=0,tot=0; scanf("%d%d ",&h,&w); for (int i=1;i<=h;i++) { for (int j=1;j<=w;j++) scanf("%c",&s[i][j]); scanf("\n"); } for (int i=1;i<=h;i++) for (int j=1;j<=w;j++) { if (s[i][j]=='.'&&s[i-1][j]=='.') sum[i][j][0]=1; if (s[i][j]=='.'&&s[i][j-1]=='.') sum[i][j][1]=1; if (s[i][j]=='.'&&s[i+1][j]=='.') sum[i][j][2]=1; if (s[i][j]=='.'&&s[i][j+1]=='.') sum[i][j][3]=1; for (int k=0;k<=3;k++) sum[i][j][k]=sum[i-1][j][k]+sum[i][j-1][k]-sum[i-1][j-1][k]+sum[i][j][k]; } scanf("%d",&q); for (int i=1;i<=q;i++) { ans=0; scanf("%d%d%d%d",&t,&l,&b,&r); ans+=sum[t][r][0]-sum[t-1][r][0]-sum[t][l-1][0]+sum[t-1][l-1][0]; ans+=sum[b][l][1]-sum[t-1][l][1]-sum[b][l-1][1]+sum[t-1][l-1][1]; ans+=sum[b][r][2]-sum[b-1][r][2]-sum[b][l-1][2]+sum[b-1][l-1][2]; ans+=sum[b][r][3]-sum[t-1][r][3]-sum[b][r-1][3]+sum[t-1][r-1][3]; tot=0; for (int j=0;j<=3;j++) tot+=sum[b][r][j]-sum[t-1][r][j]-sum[b][l-1][j]+sum[t-1][l-1][j]; tot=(tot-ans)/2; printf("%I64d\n",tot); } return 0; }D题问l-r之间有多少个形如k^n的数。。。直接暴力就好了,把unsigned
long long 判一下
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> using namespace std; unsigned long long l,r,k,tot=0; const unsigned long long N=9223372036854775808ULL; int main() { scanf("%I64u%I64u%I64u",&l,&r,&k); for (unsigned long long tmp=1,tmp2;tmp<=r;tmp2=tmp,tmp*=k) { if (tmp2>(N/k)) break; if (tmp>=l) { if (tot!=0) printf(" "); printf("%I64u",tmp); tot++; } } if (tot==0) printf("-1"); return 0; }E题只要求多边形到多边形外一点的最远距离和最近距离就好,最远距离是顶点,最近距离可能是在边上,我判断的时候用叉积判断的,求距离也是用面积除以底算的,这样感觉比较稳,
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int n; double x[100100],y[100100],px,py; double sqr(double x) {return x*x;} double cj(double x1,double y1,double x2,double y2) { return (x1-px)*(y2-py)-(x2-px)*(y1-py); } int main() { double maxf=0; double minf=1000000000000; scanf("%d%lf%lf",&n,&px,&py); for (int i=1;i<=n+1;i++) { if (i<=n) { scanf("%lf%lf",&x[i],&y[i]); maxf=max(maxf,sqr(x[i]-px)+sqr(y[i]-py)); minf=min(minf,sqr(x[i]-px)+sqr(y[i]-py)); } else { x[i]=x ; y[i]=y ; } int tmp; if (i==1) continue; if (i>1&&i<=n) tmp=i-1; else tmp=1; if (fabs(x[i]-x[tmp])<1e-6) { if (((py>y[i]&&py<y[tmp])||(py>y[tmp]&&py<y[i]))&&minf>sqr(x[i]-px)) minf=sqr(x[i]-px); } else if (fabs(y[i]-y[tmp])<1e-6) { if (((px>x[i]&&px<x[tmp])||(px>x[tmp]&&px<x[i]))&&minf>sqr(y[i]-py)) minf=sqr(y[i]-py); } else { double k=-(x[tmp]-x[i])/(y[tmp]-y[i]); double tmpx=px+1; double tmpy=py+k; if (cj(tmpx,tmpy,x[i],y[i])*cj(tmpx,tmpy,x[tmp],y[tmp])<0) minf=min(minf,sqr(fabs(cj(x[i],y[i],x[tmp],y[tmp])))/(sqr(x[tmp]-x[i])+sqr(y[tmp]-y[i]))); } } printf("%.18f",(maxf-minf)*3.14159265358979323846264338); return 0; }
F题是本次的防AK题,其实也什么难度。。只是比较绕,具体题解
传送门:http://blog.csdn.net/pro_space/article/details/50603622
祝大家训练愉快~
相关文章推荐
- 安卓智能指针
- overridePendingTransition
- spring IOC的理解
- 【Redis test】You need tcl 8.5 or newer in order to run the Redis test
- 两个任意长度的长整数相乘(C语言、双向链表方法)
- Android开发刷新相册问题!!
- WordPress优化:修改文章标签为彩色标签
- [html5]动态多边形flat-surface-shader
- 快过年了
- CentOS6.5下修改MySQL编码方法
- [LeetCode]162. Find Peak Element
- swap file "*.swp" already exists!的解决方法
- 自定义控件中如何实现按钮之间的共轭?
- 51Nod 1046 A^B Mod C(快速幂)
- 【Linux】SVN的安装和配置
- sqlserver重置标识
- category和extension
- strace命令入门
- java深入理解反射机制
- 【jQuery基础学习】09 jQuery与前端(这章很水)