POJ 1230(贪心)
来源:互联网 发布:手机qq显示mac在线吗 编辑:程序博客网 时间:2024/05/15 18:40
/**POJ 1230 题意:魔术师穿墙,由于体力有限,最多可以穿越max个墙。要求尽可能去掉几个墙,让魔术师在每一列都可以表演顺利; 思路:贪心,按照墙的左端点从小到大排序后,从左往右开始寻找多余方格所在最长墙,尽可能的删除一个墙,去掉更多的方格 细节:墙可以是连续的,但不重叠 */ #include <algorithm>#include<cstdio>#include<cstdlib>#include<cmath>#include<iostream>using namespace std;template <class T> void swap ( T& a, T& b ) { T c(a); a=b; b=c; } struct grid{ int bx,by,ex,ey;}GridW;int cmp(const void *a, const void *b){ return (*(grid *)a).by > (*(grid *)b).by ? 1:-1;}grid g[102];int main(){ int t,n,max,i,j,k,re; cin >> t ; while(t--) { int wall[102]={0},mmax=-1;//mmax 为最右一列墙的列数 wall数组记录每列墙的个数 cin >> n >> max; for (re=i=0; i<n; i++) { cin >> g[i].by >> g[i].bx >> g[i].ey >> g[i].ex; if(g[i].by>g[i].ey) ::swap(g[i].by,g[i].ey);//前后端点无序,判断排序 if(mmax < g[i].ey) mmax = g[i].ey; for (j=g[i].by; j<=g[i].ey; j++)wall[j]++;//wall 统计各列墙的数目 } qsort(g,n,sizeof(g[0]),cmp);//按照左端点Y值从小到大排序 for (re=i=0; i<=mmax; i++) while(wall[i] > max) { int Max=-1,posi; //Max 记录可以消除当前方格所在墙的最右端列数,以便比较找到最长的墙 posi记录最长墙的下标 for (j=0; j<n; j++)//寻找方格所在最长的墙 { if(g[j].by <= i && g[j].ey>= i && g[j].ey >Max) Max = g[j].ey,posi=j; if(g[j].by > i) break; } for (j=g[posi].by; j<=g[posi].ey; j++)//更新最长墙上的方格 wall[j]--; re++;g[posi].by=g[posi].ey=0; //删除墙 } cout << re << endl; } return 0;}