noip模拟赛 whzzt-Conscience

分析:数据中并不存在无解的情况......

      每个摄像头都要覆盖尽可能多的点,按照y从小到大排序.对于每一列,只用判断第一个没有被观测到的就可以了,这个点必须要放摄像头,因为除了它自己没有其它的摄像头能观测到它了,如果它的下面有摄像头没有覆盖到,那么它就必须要观测下面,否则观测右边是最优的.

      以为会爆炸的,结果A了......

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

int T, n, m, q, visx[100010], visy[100010], ans, cantx[100010], canty[100010];
bool flag2 = false;

struct node
{
    int x, y;
}e[100010];

bool cmp(node a, node b)
{
    if (a.y == b.y)
        return a.x < b.x;
    return a.y < b.y;
}

int main()
{
    scanf("%d", &T);
    while (T--)
    {
        ans = 0;
        memset(visx, 0, sizeof(visx));
        memset(visy, 0, sizeof(visy));
        memset(cantx, 0, sizeof(cantx));
        memset(canty, 0, sizeof(canty));
        scanf("%d%d%d", &n, &m, &q);
        for (int i = 1; i <= q; i++)
            scanf("%d%d", &e[i].x, &e[i].y);
        sort(e + 1, e + 1 + q, cmp);
        for (int i = 1; i <= q; i++)
        {
            if (!cantx[e[i].x] && !canty[e[i].y] && !visx[e[i].x] && !visy[e[i].y])
            {
                bool flag = false;
                for (int j = i + 1; e[j].y == e[i].y; j++)
                {
                    if (!visx[e[j].x])
                    {
                        flag = true;
                        break;
                    }
                }
                if (flag)
                    visy[e[i].y] = 1;
                else
                    visx[e[i].x] = 1;
                cantx[e[i].x] = canty[e[i].y] = 1;
                ans++;
            }
        }
            printf("%d\n", ans);
    }

    return 0;
}

 

posted @ 2017-10-28 13:31  zbtrs  阅读(232)  评论(0编辑  收藏  举报