zoukankan      html  css  js  c++  java
  • Codeforces 724C [坐标][乱搞][模拟]

    /*
    不要低头,不要放弃,不要气馁,不要慌张
    题意:
    从(0,0)出发与x轴正方向呈45度角的射线,在给定的矩形区域内不断发射,直到射入矩形的某个角停止。
    给出多个坐标,问光线最早经过某坐标的时间。
    思路:
    1.明确光线反射次数不会超过n+m次(好像是这样==没细想)
    2.发现规律,光线要么是符合x+y=k,或者x-y=k的直线。而且每次反射都会变到不同类型的直线。
    3.知道出发点,算出反射点。
    4.把点放到直线的vector里边。每次到了某条直线把直线上的点扫一遍,然后删掉。
    
    */
    
    
    #include<bits/stdc++.h>
    using namespace std;
    struct point{
        point(){}
        point(long long xx,long long yy,int iid){
            x=xx;y=yy;id=iid;
        }
        long long x,y,id;
    };
    bool operator <(const point &a,const point &b){
        if(a.x!=b.x)return a.y<b.y;
        return a.x<b.x;
    }
    set<point> ms1[200050],ms2[200050];
    long long rel[100050];
    int n,m,k;
    point next(point a,int num){
        if(num&1){
            long long w=a.x+a.y;
            long long x=0;
            long long y=w-x;
            if(y>=0&&y<=m&&(x!=a.x||y!=a.y))return point(x,y,0);
            x=n;
            y=w-x;
            if(y>=0&&y<=m&&(x!=a.x||y!=a.y))return point(x,y,0);
            y=0;
            x=w-y;
            if(x>=0&&x<=n&&(x!=a.x||y!=a.y))return point(x,y,0);
            y=m;
            x=w-y;
            if(x>=0&&x<=n&&(x!=a.x||y!=a.y))return point(x,y,0);
        }
        else{
            long long w=a.x-a.y;
            long long x=0;
            long long y=x-w;
            if(y>=0&&y<=m&&(x!=a.x||y!=a.y))return point(x,y,0);
            x=n;
            y=x-w;
            if(y>=0&&y<=m&&(x!=a.x||y!=a.y))return point(x,y,0);
            y=0;
            x=y+w;
            if(x>=0&&x<=n&&(x!=a.x||y!=a.y))return point(x,y,0);
            y=m;
            x=y+w;
            if(x>=0&&x<=n&&(x!=a.x||y!=a.y))return point(x,y,0);
        }
    }
    long long cal(point a,point b){
        return max(a.x-b.x,b.x-a.x);
    }
    int main()
    {
        memset(rel,-1,sizeof(rel));
        long long x,y,bf=0;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=k;i++){
            scanf("%lld%lld",&x,&y);
            ms1[x-y+100000].insert(point(x,y,i));
            ms2[x+y].insert(point(x,y,i));
        }
        point st(0,0,0);
        int num=0;
        while(1){
            x=st.x;y=st.y;
            if(num&1){
                while(!ms2[x+y].empty()){
                    long long xx=ms2[x+y].begin()->x;
                    long long yy=ms2[x+y].begin()->y;
                    int id=ms2[x+y].begin()->id;
                    if(rel[id]==-1)
                    rel[id]=bf+cal(point(xx,yy,0),st);
                    ms1[x-y+100000].erase(point(xx,yy,0));
                    ms2[x+y].erase(point(xx,yy,0));
                }
            }
            else{
                while(!ms1[x-y+100000].empty()){
                    long long xx=ms1[x-y+100000].begin()->x;
                    long long yy=ms1[x-y+100000].begin()->y;
                    int id=ms1[x-y+100000].begin()->id;
                    if(rel[id]==-1)
                    rel[id]=bf+cal(point(xx,yy,0),st);
                    ms1[x-y+100000].erase(point(xx,yy,0));
                    ms2[x+y].erase(point(xx,yy,0));
                }
            }
            bf+=cal(st,next(st,num));
            st=next(st,num);
            num++;
            if((st.x==0&&st.y==0)||(st.x==0&&st.y==m)||(st.x==n&&st.y==0)||(st.x==n&&st.y==m))break;
        }
        for(int i=1;i<=k;i++){
            printf("%lld
    ",rel[i]);
        }
    }
  • 相关阅读:
    MFC对话框编程四:输入焦点的传递
    lua笔记 一个C++调用lua函数的类的实现
    [置顶] 设计模式之享元模式
    扩展实现PHP Benchmark
    TLD如何运行OpenTLD(TLD_HY20121127)
    [Oracle] Kill Session 经验总结
    php 该如何获取从百度搜索进入网站的关键词
    php+js实现百度地图多点标注的方法
    laraveladmin 报错 Disk [admin] not configured, please add a disk config in `config/filesystems.php`....
    PHP获取当前页面的url
  • 原文地址:https://www.cnblogs.com/tun117/p/5943929.html
Copyright © 2011-2022 走看看