poj1230 Pass-Muraille

来源:互联网 发布:php上传文件函数 编辑:程序博客网 时间:2024/06/18 05:56
题意 : 有一块棋盘式的场地和一个魔术师,场地中有n道墙,魔术师一次最多能穿越k道墙。求移除最少数量的墙,使得魔术师可以在场地的任意一列表演都可以成功。
/*本题使用贪心:1.使用一个结构体Wall进行存储2.对所有的墙进行排列(按墙的左端点进行排列)3.每次对同一列上的墙进行扫描,若无法穿墙,就寻找出对后续的墙影响最大的那一堵,也就是右端点最大的一堵*/#include<iostream>#include<algorithm>using namespace std;struct Point{double x,y;};struct Wall{Point left,right;//墙的左端点以及右端点}w[105];bool cmp(Wall w1,Wall w2){if(w1.left.x==w2.left.x) return w1.right.x<w2.right.x;else return w1.left.x<w2.left.x;}int search(int n,int k) //贪心{if(k==0) return n;int t1,t,i;int flag[105]={0}; //墙的标记,若已移去,则为1for(i=k;i<n;i++){t=i;t1=1;int count=0;while(t--)   //对之前所有墙进行扫描{if(t1>i) break;else if(w[i].left.x>w[i-t1].right.x && flag[i-t1]==0){t1++;}else if(w[i].left.x<=w[i-t1].right.x)     //两墙在同一列{if(flag[i-t1])   //若墙已经移去,则继续向前扫描{while(flag[i-t1]){t1++;}t++;}else{t1++;count++;}}}if(count>=k) //判断是否满足同一列上是否有k堵墙{int no=i;double max=w[i].right.x;t=i;t1=1;while(t--){if(t1>=i) break;else if(w[i-t1].right.x>max){if(flag[i-t1]){while(flag[i-t1]){t1++;}t++;}else{max=w[i-t1].right.x;no=i-t1;t1++;}}else t1++;}flag[no]=1;  }}int ans=0;for(i=0;i<n;i++){if(flag[i]) ans++;  }return ans;}int main(){int t,n,k,i,x;while(scanf("%d",&t)!=EOF){for(x=0;x<t;x++){scanf("%d%d",&n,&k);for(i=0;i<n;i++){scanf("%lf %lf %lf %lf",&w[i].left.x,&w[i].left.y,&w[i].right.x,&w[i].right.y);if(w[i].left.x>w[i].right.x)  //易忽略的地方{double temp=w[i].left.x;w[i].left.x=w[i].right.x;w[i].right.x=temp;}}sort(w,w+n,cmp);printf("%d\n",search(n,k));}}return 0;}


                                             
0 0
原创粉丝点击