poj 1230 Pass-Muraille

来源:互联网 发布:56视频相册制作软件 编辑:程序博客网 时间:2024/06/14 07:25

poj  1230  Pass-Muraille                      题目链接:http://poj.org/problem?id=1230

贪心水

题目大意:魔术师要表演穿墙魔术,舞台上有墙,魔术师有k单位的能量,也就是说他能穿过k面墙,但舞台上的墙可能会有多于k面的情况,问最少要拆几面墙,使得魔术师能表演成功?

题目分析:舞台是一个二维数组,墙都是横的,魔术师表演时则是按列走,所以我想可以用一个一维数组存下当前每一列的状态(有多少层墙),然后通过遍历一维数组来判断这一列是拆还是不拆。如果需要拆,就要选择拆哪一面(拆墙一拆拆一面,而不是拆一格,一开始没理解好),分析可得,拆对后面影响最大的墙是最优方案,也就是要拆从此点到右边距离最远的一面(或几面墙)。代码中拆墙动作循环边界为j<status[i]-k+j,最后还要加个j,原因是每拆一面墙,status[i]当前位置就要减1,边界变了,要使它不变,就要加上j。

code:

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;struct node{int wl,wr,wtr;//wall left,wall right,wall to right}wall[150];int cmp(node a,node b){return a.wtr>b.wtr?1:0;}int main(){int t,n,k,nothing,status[150],max_r,ans;scanf("%d",&t);while(t--){scanf("%d%d",&n,&k);ans=max_r=0;memset(status,0,sizeof(status));for(int i=0;i<n;i++){scanf("%d%d%d%d",&wall[i].wl,¬hing,&wall[i].wr,¬hing);if(wall[i].wl>wall[i].wr)//坑啊,一开始没注意到这个{nothing=wall[i].wl;wall[i].wl=wall[i].wr;wall[i].wr=nothing;}if(wall[i].wr>max_r)max_r=wall[i].wr;for(int j=wall[i].wl;j<=wall[i].wr;j++){status[j]++;}}for(int i=0;i<=max_r;i++){//printf("status[%d]-%d=%d\n",status[i],k,status[i]-k);if(status[i]>k){for(int j=0;j<n;j++)//找对后面影响最远的 {if(wall[j].wl>i)wall[j].wtr=0;//把当前列无墙的赋0 else wall[j].wtr=wall[j].wr-i;}sort(wall,wall+n,cmp);for(int j=0;j<status[i]-k+j;j++)//拆墙的动作在这里 改了 !!!!!!!{//printf("走了一遍j=%d,status[i]-k=%d\n",j,status[i]-k);for(int jk=wall[j].wl;jk<=wall[j].wr;jk++){status[jk]--;//具体拆,状态减 }for(int jk=0;jk<=max_r;jk++){//printf("%d",status[jk]);}//putchar('\n');wall[j].wl=wall[j].wr=wall[j].wtr=0;//拆完赋0 ans++;}//sort(wall,wall+n,cmp);//n-=status[i]-k;}}printf("%d\n",ans);}return 0;}/*18 20 0 0 00 1 0 15 0 5 05 1 5 11 1 4 10 2 2 23 2 5 24 3 1 3*//*15 21 0 1 01 0 1 01 9 1 91 9 1 91 2 1 2*//*14 21 0 1 01 3 1 31 9 1 91 2 1 2*/
PS:实在不容易,一个小错折腾了一天多,code中带的测试数据后两个对我的错误有参考意义,很多网上的测试数据都对了,但还是WA,无语……

http://blog.sina.com.cn/s/blog_64018c250100wkju.html这篇blog很厉害的样子,最下面那个程序像是生成测试数据用的,不大懂……






原创粉丝点击