题意
在 Windows 的“画图”工具里,可以绘制各种各样的图案。可以把画图当做一个标准的二维平面,在其上先后绘制了 n 条颜色互不相同的线段。
按绘制的时间顺序,从先到后把线段依次编号为 1 到 n。第 i 条线段的两个端点分别为 (xai ,yai) 和 (xbi,ybi),线段的粗细忽略不计。后绘制的线段不会改变之前绘制的线段的位置。
请写一个程序,回答 q 组询问,每组询问给出一个坐标 (xi,yi),你需要算出在这个点上最后绘制的线段编号。
思路
对于每一条线段,求出向量横纵坐标最大公约数,那么每一次横坐标加上向量横坐标除这个最大公约数的值,纵坐标加上向量纵坐标除以这个最大公约数的值,就可以到达下一个整点,不过横着的线段和竖着的线段要特殊处理,每一次更新到的点的答案,最后对于每组询问直接输出答案即可
代码
#include <cstdio>
#include <cmath>
#include <cstdlib>
int ans[251][251];
int gcd(int a,int b)
{
if(a%b==0)
return b;
else if(b%a==0)
return a;
else if(a>b)
return gcd(b,a%b);
else return gcd(a,b%a);
}
int main()
{
int n,m,xa,ya,xb,yb,g,xadd,yadd,q,x,y;
scanf("%d%d",&n,&m);
for(int k=1;k<=n;k++)
{
scanf("%d%d%d%d",&xa,&ya,&xb,&yb);
if(xa!=xb&&ya!=yb)
{
g=gcd(abs(xa-xb),abs(ya-yb));
xadd=(xb-xa)/g;
yadd=(yb-ya)/g;
}
else if(xa==xb)
{
xadd=0;
yadd=(yb-ya)/abs(yb-ya);
}
else
{
xadd=(xb-xa)/abs(xb-xa);
yadd=0;
}
for(int i=xa,j=ya;i!=xb&&j!=yb;i+=xadd,j+=yadd)
ans[i][j]=k;
ans[xb][yb]=k;
}
scanf("%d",&q);
for(int i=0;i<q;i++)
{
scanf("%d%d",&x,&y);
printf("%d\n",ans[x][y]);
}
return 0;
}