2017 计蒜之道 复赛 B. Windows 画图 坐标描点

    当时报名参加了计蒜客,然后初赛6场我只打了一场,而且那一场我只做出来一道题(那场被一群python用户血虐),之后又是打蓝桥杯又是有别的事的都没打,结果突然收到短信说进复赛了......

    好吧,反正现在也是找题做以防手生,做做吧。(不过最后只做出了这一道.....百度地图导航那道题各种超内存后来就干脆挂机不做了= =)


    下面是题目:

    在 Windows 的“画图”工具里,可以绘制各种各样的图案。可以把画图当做一个标准的二维平面,在其上先后绘制了 nnn 条颜色互不相同的线段。

    按绘制的时间顺序,从先到后把线段依次编号为 111nnn。第iii 条线段的两个端点分别为 (xai,yai)(xa_i,ya_i)(xai,yai)(xbi,ybi)(xb_i,yb_i)(xbi,ybi),线段的粗细忽略不计。后绘制的线段不会改变之前绘制的线段的位置。

    请写一个程序,回答 qqq 组询问,每组询问给出一个坐标 (xi,yi)(x_i,y_i)(xi,yi),你需要算出在这个点上最后绘制的线段编号。


输入格式   

    第一行包含两个正整数 n,m(1≤n≤80000,1≤m≤250)n,m(1\leq n\leq 80000,1\leq m\leq 250)n,m(1n80000,1m250),分别表示线段的数目以及坐标的最大取值(下面会具体说明)。

    接下来 nnn 行,每行输入四个正整数 xai,yai,xbi,ybixa_i,ya_i,xb_i,yb_ixai,yai,xbi,ybi(1≤xai,yai,xbi,ybi≤m,(1\leq xa_i,ya_i,xb_i,yb_i\leq m,(1xai,yai,xbi,ybim,(xai,yai)≠(xbi,ybi))(xa_i,ya_i)\neq(xb_i,yb_i))(xai,yai)(xbi,ybi)),依次表示每条线段两个端点的坐标。

    接下来一行,输入一个正整数 q(1≤q≤62500)q(1\leq q\leq 62500)q(1q62500),表示询问的组数。

    接下来 qqq 行,每行输入两个正整数 xi,yi(1≤xi,yi≤m)x_i,y_i(1\leq x_i,y_i\leq m)xi,yi(1xi,yim),分别表示每组询问的坐标。


输出格式

    输出 qqq 行,每行一个整数,表示该位置最上面(最后绘制)的线段的编号。

    若该点上不存在线段,请输出 000


样例解释

    样例对应题目描述中的图。


样例输入

5 8
2 5 5 2
5 2 3 8
8 4 1 4
2 2 5 8
8 7 4 1
4
3 4
5 2
6 4
3 5

样例输出

4
2
5
0

    一开始浏览题的时候看见这题有个图还有各种线觉得可能不好做没再细看,结果百度那个题没做出来再回来看发现这题已经A了一群人了....题意就是连一堆各种颜色的线段,问你某个点最后的颜色。主要这些点都是整数,这就比较好做了,颜色只需要求最后一次染的,这也很方便,有新的线段的时候颜色直接覆盖就行了。在找线段的时候,因为都是整数,所以只要求出线段两头的比例,再找出中间都有哪些整数点并染色就可以了。

    下面AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int color[305][305];

int gcd(int a,int b)
{
    return a%b?gcd(b,a%b):b;
}

int main()
{
    int n,m;
    int i;
    int x1,y1,x2,y2;
    int x,y;
    int fx,fy;
    int tim;
    int T;
    int t;
    int g;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(color,0,sizeof(color));
        for(i=1;i<=n;i++)
        {
            fx=-1;
            fy=-1;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            color[x1][y1]=i;
            color[x2][y2]=i;
            if(x1<x2)
                fx=1;
            if(y1<y2)
                fy=1;
            x=abs(x1-x2);
            y=abs(y1-y2);
            if(x==0)
            {
                y--;
                while(y--)
                {
                    y1+=fy;
                    color[x1][y1]=i;
                    //cout<<"1color["<<x1<<"]["<<y1<<"] = "<<i<<endl;
                }
                continue;
            }
            if(y==0)
            {
                x--;
                while(x--)
                {
                    x1+=fx;
                    color[x1][y1]=i;
                    //cout<<"2color["<<x1<<"]["<<y1<<"] = "<<i<<endl;
                }
                continue;
            }
            g=gcd(x,y);
            if(x%y==0||y%x==0)
            {
                if(x<y)
                {
                    t=x;
                    x/=t;
                    y=y/t;
                }
                else if(x>y)
                {
                    t=y;
                    y/=t;
                    x=x/t;
                }
                else
                {
                    t=x;
                    y/=t;
                    x/=t;
                }
                while(x1!=x2)
                {
                    x1+=fx*x;
                    y1+=fy*y;
                    color[x1][y1]=i;
                    //cout<<"3color["<<x1<<"]["<<y1<<"] = "<<i<<endl;
                }
            }
            else if(g!=x&&g!=y)
            {
                if(x<y)
                {
                    x/=g;
                    y=y/g;
                }
                else if(x>y)
                {
                    y/=g;
                    x=x/g;
                }
                else
                {
                    y/=g;
                    x/=g;
                }
                while(x1!=x2)
                {
                    x1+=fx*x;
                    y1+=fy*y;
                    color[x1][y1]=i;
                    //cout<<"4color["<<x1<<"]["<<y1<<"] = "<<i<<endl;
                }
            }
            //cout<<i<<" color is over"<<endl;
        }
        scanf("%d",&T);
        for(i=0;i<T;i++)
        {
            scanf("%d%d",&x,&y);
            cout<<color[x][y]<<endl;
        }
    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值