Codeforces Round Intel Code Challenge Final Round C. Ray Tracing

来源:互联网 发布:linux 安装服务 编辑:程序博客网 时间:2024/06/09 19:55

题目大意:光线从(0,0)点出发斜向上45°角,速度为√2。平面上有若干个点,问每个点第一次被光线穿过的时间,未被穿过输出-1


似乎可以用CRT做,但是我写的是大模拟。

因为碰撞点只有4(n+m)个,而且每条对角线只可能经过一次。

因此我们每次计算出下一次碰撞点和碰撞时间,把时间加入该对角线的信息

最后枚举每一个点和经过它的两条对角线,计算答案即可


#include<set>#include<map>#include<cmath>#include<queue>#include<vector>#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<algorithm>using namespace std;struct point{int x,y;}p[1000001];bool v1[1000001],v2[1000001],v3[1000001],v4[1000001];struct info{int xx,yy;long long x;int p;}a[1000001],b[1000001];long long ans[1000001];/*\1   下1/2   上1\3   上-1/4   下-1*/int main(){int n,m,k;scanf("%d%d%d",&n,&m,&k);int i;for(i=1;i<=k;i++)scanf("%d%d",&p[i].x,&p[i].y);int w=1,x=0,y=0;long long t=0;while(1){if(w==1){a[x-y+100000].x=t;a[x-y+100000].p=1;a[x-y+100000].xx=x;a[x-y+100000].yy=y;if(n-x<m-y){y+=n-x;t+=(long long)(n-x);x=n;w=2;}else{x+=m-y;t+=(long long)(m-y);y=m;w=4;}}else if(w==2){b[x+y].x=t;b[x+y].p=1;b[x+y].xx=x;b[x+y].yy=y;if(x<m-y){y+=x;t+=(long long)x;x=0;w=1;}else{x-=m-y;t+=(long long)(m-y);y=m;w=3;}}else if(w==3){a[x-y+100000].x=t;a[x-y+100000].p=-1;a[x-y+100000].xx=x;a[x-y+100000].yy=y;if(x<y){y-=x;t+=(long long)x;x=0;w=4;}else{x-=y;t+=(long long)y;y=0;w=2;}}else if(w==4){b[x+y].x=t;b[x+y].p=-1;b[x+y].xx=x;b[x+y].yy=y;if(n-x<y){y-=n-x;t+=(long long)(n-x);x=n;w=3;}else{x+=y;t+=(long long)y;y=0;w=1;}}if(x==0){if(v1[y])break;v1[y]=true;}else if(x==n){if(v2[y])break;v2[y]=true;}else if(y==0){if(v3[x])break;v3[x]=true;}else if(y==n){if(v4[x])break;v4[x]=true;}}memset(ans,127/3,sizeof(ans));for(i=1;i<=k;i++){long long t1=-1,t2=-1;int x1=p[i].x-p[i].y+100000,x2=p[i].x+p[i].y;if(a[x1].p==1&&a[x1].p!=0){if(a[x1].xx==0)t1=a[x1].x+p[i].x;elset1=a[x1].x+p[i].y;}else if(a[x1].p!=0){if(a[x1].yy==m)t1=a[x1].x+m-p[i].y;elset1=a[x1].x+n-p[i].x;}if(b[x2].p==1&&b[x2].p!=0){if(b[x2].xx==n)t2=b[x2].x+n-p[i].x;elset2=b[x2].x+p[i].y;}else if(b[x2].p!=0){if(b[x2].yy==m)t2=b[x2].x+m-p[i].y;elset2=b[x2].x+p[i].x;}if(t1!=-1){if(t2!=-1)ans[i]=min(t1,t2);elseans[i]=t1;}else if(t2!=-1)ans[i]=t2;}for(i=1;i<=k;i++){if(ans[i]>(long long)100000000000)printf("-1\n");elseprintf("%I64d\n",ans[i]);}return 0;}


0 0