/**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;
}
POJ 1230(贪心)
最新推荐文章于 2018-09-03 20:07:07 发布