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);
        }
    }
}
原文地址:https://www.cnblogs.com/tun117/p/5372393.html