ACM/ICPC 2014 北京站题 解题报告

来源:互联网 发布:国密sm4算法 编辑:程序博客网 时间:2024/06/03 00:08

A题好福利,哇哈哈

#include<cstdio>#include<memory>using namespace std;int data[1000010];double dmax(double a,double b){return a>b?a:b;}int abs(int a){return a>0?a:-a;}int main(){int t,tn,n,i,j;double max;scanf("%d",&t);for(tn=1;tn<=t;tn++){scanf("%d",&n);memset(data,-1,sizeof(data));for(i=1;i<=n;i++){scanf("%d",&j);scanf("%d",&data[j]);}j=-1;max=-1.0;for(i=0;i<=1000010;i++) if(data[i]!=-1){if(j!=-1) max=dmax(max,(double)abs(data[i]-data[j])/(double)(i-j));j=i;}printf("Case #%d: %.2lf\n",tn,max);}return 0;}

B题 我试着从右上沿对角线填,每填完一种颜色换下一种颜色,填完一半并填完当前颜色以后,剩下的就可以随便填了,5x5以内能AC,数据再大我也没把握,但我觉得这种填法挺有意思的

15ms Accept!!

--------------------------------------

#include<cstdio>#include<algorithm>using namespace std;typedef struct{int index;int number;int used;}color;bool cmp(color a,color b){return a.number>b.number;}color c[26];int map[6][6],n,m,k,hmax;int nextcolor(int l){int i,mmax=0,ncl=0;for(i=1;i<=k;i++) if(!c[i].used&&c[i].number<=l&&mmax<c[i].number){mmax=c[i].number;ncl=i;}if(ncl==0) for(i=k;i>=1;i--) if(!c[i].used) {ncl=i;break;}c[ncl].used=1;return ncl;}void printmap(){int sum,i,j,d,p;if(n*m%2==0) j=m-1;else j=m;d=j>0?0:1;p=1;c[1].used=1;sum=c[1].number;for(i=1;i<=hmax;i++){map[1+d][j+d]=c[p].index;if(--c[p].number==0){p=nextcolor(hmax-sum);sum+=c[p].number;}d++;if(j+d>m||1+d>n){j-=2;d=0;while(j+d<1) d++;}}if(n*m%2==0) j=m;else j=m-1;d=j>0?0:1;if(sum!=hmax){while(c[p].number){map[1+d][j+d]=c[p].index;if(--c[p].number==0) break;d++;if(j+d>m||1+d>n){j-=2;d=0;while(j+d<1) d++;}}p=nextcolor(0);}for(i=1;i<=n;i++)for(j=1;j<=m;j++)if(!map[i][j]){map[i][j]=c[p].index;if(--c[p].number==0) p=nextcolor(0);}for(i=1;i<=n;i++){printf("%d",map[i][1]);for(j=2;j<=m;j++) printf(" %d",map[i][j]);printf("\n");}}int main(){int t,tn,i;scanf("%d",&t);for(tn=1;tn<=t;tn++){scanf("%d %d %d",&n,&m,&k);for(i=1;i<=k;i++){c[i].index=i;c[i].used=0;scanf("%d",&c[i].number);}sort(c+1,c+1+k,cmp);hmax=(int)((double)n*m/2.0+0.5);printf("Case #%d:\n",tn);if(c[1].number>hmax) printf("NO\n");else{memset(map,0,sizeof(map));printf("YES\n");printmap();}}return 0;}

C题 最小公倍数的题,做完D再回来做

--------------------------------------------

问题并不复杂,常见的运动分解,在x,y轴两个分解运动的公共周期内如果不会碰撞就永远不会碰撞

数据非常大,需要用到64位int,否则计算lcm(2x,2y)会溢出,判断在公共周期内两坐标轴是否会同时碰撞时我采用了二分搜索,187msAC

从开始写到AC花了快1个小时的时间。。。昨天的思考时间无法计算。。。我果然太小看ACM了啊。。。乖乖刷水题去好了

#include<cstdio>double tx[1000001],ty[1000001];int gcd(int a,int b){if(a%b==0) return b;else return gcd(b,a%b);}int abs(int a){return a>0?a:-a;}int max(int a,int b){return a>b?a:b;}double hilove(int p1,int p2,__int64 l){if(p1==p2) return 0;return abs(p1-p2)/2.0+l-max(p1,p2);}double locate(int s,__int64 l,double t){while(t>2*l) t-=2*l;if(t<=l-s) return s+t;if(t>l-s&&t<=2*l-s) return 2*l-t-s;if(t>2*l-s) return t-2*l+s;}int binary_search(int l,int r,double t){      int mid=(r+l)/2;      if(tx[mid]==t) return mid;if(mid==l) return 0;    if(tx[mid]>t) binary_search(l,mid,t);      else binary_search(mid,r,t);}int main(){__int64 xyl,xl,yl;int t,tn,x1,x2,y1,y2,txl,tyl,i,pos;scanf("%d",&t);for(tn=1;tn<=t;tn++){scanf("%I64d %I64d\n%d %d %d %d",&xl,&yl,&x1,&y1,&x2,&y2);xyl=xl/gcd(xl,yl)*yl*2;tx[1]=hilove(x1,x2,xl);ty[1]=hilove(y1,y2,yl);printf("Case #%d:\n",tn);if(tx[1]==0&&ty[1]==0){printf("%.1lf %.1lf\n",(double)x1,(double)y1);continue;}if(tx[1]==0){printf("%.1lf %.1lf\n",locate(x1,xl,ty[1]),locate(y1,yl,ty[1]));continue;}if(ty[1]==0){printf("%.1lf %.1lf\n",locate(x1,xl,tx[1]),locate(y1,yl,tx[1]));continue;}for(txl=1;tx[txl]<=xyl;txl++) tx[txl+1]=tx[txl]+xl;for(tyl=1;ty[tyl]<=xyl;tyl++) ty[tyl+1]=ty[tyl]+yl;for(i=1;i<tyl;i++) if(pos=binary_search(1,txl,ty[i])) break;if(!pos) printf("Collision will not happen.\n");else printf("%.1lf %.1lf\n",locate(x1,xl,ty[i]),locate(y1,yl,ty[i]));}}

 

 

D题 折腾了挺久的,今天精神不好,睡了3个小时没到,晚上回去一定好好补觉啊魂淡,头等大事就是睡觉啊魂淡!!!有什么事情有这个重要啊魂淡魂淡魂淡!!

#include<cstdio>#include<memory>using namespace std;int dp[202][202];int vis[202][202];int eh[202];int min(int a,int b){return a<b?a:b;}int main(){int t_t,t_tt,n,ah,sum,i,k,d;scanf("%d",&t_tt);for(t_t=1;t_t<=t_tt;t_t++){scanf("%d",&n);sum=0;for(i=1;i<=n;i++){scanf("%d",&ah);sum+=ah;}for(i=1;i<=n;i++) scanf("%d",eh+i);eh[0]=eh[n+1]=0;memset(dp,0,sizeof(dp));memset(vis,0,sizeof(vis));for(i=1;i<=n;i++) dp[i][i]=eh[i-1]+eh[i+1];for(k=1;k<n;k++)for(i=1;i+k<=n;i++)for(d=i;d<=i+k;d++){if(vis[i][i+k]) dp[i][i+k]=min(dp[i][i+k],dp[i][d-1]+dp[d+1][i+k]+eh[i-1]+eh[i+k+1]);else {vis[i][i+k]=1;dp[i][i+k]=dp[i][d-1]+dp[d+1][i+k]+eh[i-1]+eh[i+k+1];}}printf("Case #%d: %d\n",t_t,sum+dp[1][n]);}}

E题 呐呐呐,我又回来了!

-------------------------

去刷水题了。。。。。。。。
 ------------------------

啦啦啦,我又萌萌哒回来啦,先说下思路,用一个矩阵保存输入的点,每当选定一个L的时候将L涉及的点从矩阵中删去,统计剩余矩阵中的所有L

这样想法是没错的。。。但是超时是肯定哒啦~~

--------------------------

哪位大腿有不TLE的码吗?给人家看看好不好。。。


 K题 签个到,我逛4399去了,\(^o^)/~

#include<cstdio>int s[3000010];int main(){int tn,tnn,n,i,min,sum;scanf("%d",&tnn);for(tn=1;tn<=tnn;tn++){scanf("%d",&n);min=10000000;sum=0;for(i=1;i<=n;i++) scanf("%d",&s[i]);for(i=n;i>=1;i--){if(s[i]>min) sum++;else min=s[i];}printf("Case #%d: %d\n",tn,sum);}return 0;}


 

0 0
原创粉丝点击