计蒜客 15967 Windows 画图 题解

时间:2021-08-28 00:39:32

题意

在 Windows 的“画图”工具里,可以绘制各种各样的图案。可以把画图当做一个标准的二维平面,在其上先后绘制了 n 条颜色互不相同的线段。
按绘制的时间顺序,从先到后把线段依次编号为 1 到 n。第 i 条线段的两个端点分别为 (xa​i​​ ,ya​i) 和 (xb​i,yb​i),线段的粗细忽略不计。后绘制的线段不会改变之前绘制的线段的位置。
请写一个程序,回答 q 组询问,每组询问给出一个坐标 (x​i​,y​i),你需要算出在这个点上最后绘制的线段编号。

思路

对于每一条线段,求出向量横纵坐标最大公约数,那么每一次横坐标加上向量横坐标除这个最大公约数的值,纵坐标加上向量纵坐标除以这个最大公约数的值,就可以到达下一个整点,不过横着的线段和竖着的线段要特殊处理,每一次更新到的点的答案,最后对于每组询问直接输出答案即可

代码

#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;
}