zoukankan      html  css  js  c++  java
  • 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);
            }
        }
    }
  • 相关阅读:
    2. Add Two Numbers
    1. Two Sum
    leetcode 213. 打家劫舍 II JAVA
    leetcode 48. 旋转图像 java
    leetcode 45. 跳跃游戏 II JAVA
    leetcode 42. 接雨水 JAVA
    40. 组合总和 II leetcode JAVA
    24. 两两交换链表中的节点 leetcode
    1002. 查找常用字符 leecode
    leetcode 23. 合并K个排序链表 JAVA
  • 原文地址:https://www.cnblogs.com/tun117/p/5372393.html
Copyright © 2011-2022 走看看