• ZOJ 3042 City Selection II 【序】【离散化】【数学】


     题意:

    输入数据n,m。n代表工厂的数量,m代表城市的数量。

    接下来n+m行为工厂和城市的坐标。

    规定如图所示方向刮风,工厂的air会污染风向地区的air。

    注意,工厂和城市的坐标表示的是从x到x+1从y到y+1之间小正方形都是工厂区域,规定如果只有一个coner的air被污染那么该地区视为无污染。

    要求输出有多少不被污染的城市。

    坑:

    思考了很多问题....

    1.加入某城市的正下方是工厂怎么办...这个是否算污染。

    2.假如有两个角被污染了怎么办...算污染吗。

    坑了一整天.没办法找大神的代码测试了几组样例...【奈何年代久远代码都不好找更不用说题解】

    总之测试结果是以上两种都不算污染。

    其实坑都是自己挖的,用正常的脑子思考下问题,就不会出问题。

    不过话说回来掉坑里不可怕,要保持冷静爬出来...

    思路:

    1.离散化,已知直线坐标,按照截距离散化。

    2.序,从坐到右从上刀下依次处理,遇到工厂更新标记数组,遇到城市检查是否被污染,无污染加入答案序列。

    3.如何处理只有两个顶点被污染的问题,这点我借鉴了大牛的思路,每个点不处理右上角的点,不管是工厂还是城市。那么城市不污染的条件是除了右上角的点以外其它三个点不被污染。证明自己画个图想想。

    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    const int inf=0x3f3f3f3f;
    int tmp;
    struct st{
        pair<int,int>me;
        bool imfac;
    };
    pair<int,int>city[100050];
    pair<int,int>fac[100050];
    int jilu[800050];
    int mynum[100050];
    bool vis[800050];
    st all[200050];
    pair<int,int>aaa[100050];
    bool cmp(st a,st b){
        if(a.me.first!=b.me.first)
            return a.me.first<b.me.first;
        else if(a.me.second!=b.me.second)return a.me.second>b.me.second;
        else return a.imfac>b.imfac;
    }
    int main()
    {
        int n,m;
        while(scanf("%d%d",&n,&m)!=EOF){
            memset(vis,0,sizeof(vis));
            int num=0,nnnn=0;
            for(int i=0;i<n;i++){
                scanf("%d%d",&fac[i].first,&fac[i].second);
                jilu[num++]=2*fac[i].first+fac[i].second;
                jilu[num++]=2*(fac[i].first+1)+fac[i].second;
                jilu[num++]=2*(fac[i].first)+fac[i].second+1;
            }
            for(int i=0;i<m;i++){
                scanf("%d%d",&city[i].first,&city[i].second);
                jilu[num++]=2*city[i].first+city[i].second;
                jilu[num++]=2*city[i].first+city[i].second+1;
                jilu[num++]=2*(city[i].first+1)+city[i].second;
            }
            sort(jilu,jilu+num);
            num=unique(jilu,jilu+num)-jilu;
            for(int i=0;i<n;i++){
                all[nnnn++].me=fac[i];
                all[nnnn-1].imfac=1;
            }
            for(int i=0;i<m;i++){
                all[nnnn++].me=city[i];
                all[nnnn-1].imfac=0;
            }
            int id,ansnum=0;
            sort(all,all+nnnn,cmp);
            for(int i=0;i<nnnn;i++){
                if(all[i].imfac){
                id=upper_bound(jilu,jilu+num,2*all[i].me.first+all[i].me.second)-jilu;
                vis[id]=1;
                id=upper_bound(jilu,jilu+num,2*all[i].me.first+all[i].me.second+1)-jilu;
                vis[id]=1;
                id=upper_bound(jilu,jilu+num,2*(all[i].me.first+1)+all[i].me.second)-jilu;
                vis[id]=1;
                }
                else{
                    int ttt=0;
                    id=upper_bound(jilu,jilu+num,2*(all[i].me.first)+all[i].me.second)-jilu;
                    ttt+=vis[id];
                    id=upper_bound(jilu,jilu+num,2*(all[i].me.first)+all[i].me.second+1)-jilu;
                    ttt+=vis[id];
                    id=upper_bound(jilu,jilu+num,2*(all[i].me.first+1)+all[i].me.second)-jilu;
                    ttt+=vis[id];
                    if(ttt==0){
                    aaa[ansnum++]=all[i].me;
                    }
                }
            }
            sort(aaa,aaa+ansnum);
            printf("%d
    ",ansnum);
            for(int i=0;i<ansnum;i++){
                printf("(%d,%d)
    ",aaa[i].first,aaa[i].second);
            }
        }
    }
  • 相关阅读:
    最详细最权威的Android 编码规范
    一款实用的工具手机软件
    一个简单的四则运算程序(优化)
    随笔
    一个简单的四则运算程序
    随手记(四)
    随手记(三)
    随手记(二)
    随手记(一)
    大学生生活中的三大痛点
  • 原文地址:https://www.cnblogs.com/tun117/p/5372393.html
Copyright © 2020-2023  润新知