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; }