1116:Library 图书馆(已翻译)

描述

Castaway Robinson Crusoe is living alone on a remote island. One day a ship carrying a royal library has wrecked nearby. Usually Robinson brings any useful stuff from the shipwreck to his island, and this time he has brought a big chest with books.

Robinson has decided to build a bookcase for these books to create his own library. He cut a rectangular niche in the rock for that purpose, hammered in wooden pegs, and placed wooden planks on every pair of pegs that have the same height, so that all planks are situated horizontally and suit to act as shelves.

Unfortunately, Robinson has discovered that one especially old and big tome does not fit in his bookcase. He measured the height and width of this tome and has decided to redesign his bookcase in such a way, as to completely fit the tome on one of the shelves, taking into account locations of other shelves and the dimensions of the niche. With each shelf in the bookcase, one of the following operations should be made:


1. Leave the shelf on its original place.

2. Move the shelf to the left or to the right.

3. Shorten the shelf by cutting off a part of the plank and optionally move it to the left or to the right.

4. Move one of the pegs to a different place at the same height and move the shelf to the left or to the right.

5. Shorten the shelf by cutting off a part of the plank, move one of the pegs to a different place at the same height, and optionally move the shortened shelf to the left or to the right.

6. Remove the shelf from the bookcase along with both supporting pegs.

We say that the shelf is properly supported by its pegs, if exactly two distinct pegs support the shelf and the center of the shelf is between its pegs or coincides with one of the pegs. The original design of Robinson's library has all the shelves properly supported by their pegs and lengths of all shelves are integer number of inches. The Robinson may only cut an integer number of inches from the planks, because he has no tools for more precise measurements. All remaining shelves after the redesign must be properly supported by their pegs.

You are to find the way to redesign Robinson's library to fit the special old tome without changing original design too much. You have to minimize the number of pegs that are to be removed from their original places during the redesign (operations 4 and 5 remove one peg, and operation 6 removes two pegs). If there are different ways to solve the problem, then you are to find the one that minimizes the total length of planks that are to be cut off (operations 3 and 5 involve cutting something from the planks, and operation 6 counts as if cutting off the whole plank). Width of planks and diameter of pegs shall be considered zero.

The tome may not be rotated. The tome should completely (to all its width) stand on one of the shelves and may only touch other shelves, their pegs or niche's edge.

漂流者鲁滨逊漂流记独自生活在一个偏远的小岛上。一天,一艘载有皇家图书馆的船在附近失事。

罗宾逊经常从沉船上带一些有用的东西到他的岛上,这次他带了一个装满书的大箱子。罗宾逊已经决定为这些书建一个书架来创建他自己的图书馆。为此,他在岩石上开凿了一个长方形的壁龛,用木桩锤打,并在每对高度相同的木桩上放置木板,这样所有的木板都水平放置,适合作为架子。

不幸的是,罗宾逊发现他的书柜里放不下一本特别古老的大书。他测量了这本书的高度和宽度,并决定重新设计他的书架,以便完全适合在一个书架上的书籍,考虑到其他书架的位置和壁龛的尺寸。对于书架上的每一个架子,都应进行以下操作之一:

1、把架子放在原来的地方。

2、把架子移到左边或者右边。

3、通过切断一部分木板来缩短架子,并且可以选择将它移动到左边或者右边。

4、把其中一个钉子移到相同高度的另一个地方,把架子移到左边或右边。

5、通过切断木板的一部分来缩短架子,移动其中一个钉子到相同高度的不同位置,并且可以选择将缩短的架子向左或向右移动。

6、将书架连同两个支撑柱从书架上移开。

我们说,如果两个不同的钉子恰好支撑着架子,而且架子的中心在它的钉子之间或与其中一个钉子重合,那么架子就由它的钉子正确地支撑着。罗宾逊图书馆的原始设计中,所有的书架都有固定支架,书架的长度都是整数英寸。罗宾逊可能只能从木板上切下整数英寸,因为他没有更精确的测量工具。重新设计后所有剩余的货架都必须有适当的钉子支撑。

你要找到重新设计罗宾逊的图书馆的方法,以适应特殊的旧书,而不改变原来的设计太多。在重新设计过程中,你必须尽量减少需要从原始位置移除的钉子的数量(操作4和5移除一个钉子,操作6移除两个钉子)。如果有不同的方法来解决这个问题,那么你应该找到一个最小化木板总长度的方法(操作3和操作5包括从木板上切下一些东西,操作6就好像切掉了整个木板一样)。木板的宽度和钉子的直径应视为零。

这本书不能旋转。这本书应该完全(尽其所有宽度)站在一个架子上,可以只接触其他架子,他们的钉子或壁龛的边缘。

输入
The first line of the input file contains four integer numbers XN, YN, XT, and YT, separated by spaces. They are, correspondingly, width and height of the niche, and width and height of the old tome in inches (1 <= XN, YN, XT, YT <= 1000).

The second line of the input file contains a single integer number N (1 <= N <= 100) that represents the number of the shelves. Then N lines follow. Each line represents a single shelf along with its two supporting pegs, and contains five integer numbers yi, xi, li, x1i, x2i, separated by spaces, where:

?yi (0 < yi < YN) - the height of the ith shelf above the bottom of the niche in inches.
?xi (0 <= xi < XN) - the distance between the left end of the ith shelf and the left edge of the niche in inches.
?li (0 < li <= XN - xi) - the length of the ith shelf in inches.
?x1i (0 <= x1i <= li/2) - the distance between the left end of the ith shelf and its leftmost supporting peg in inches.
?x2i (li/2 <= x2i <= li; x1i < x2i) - the distance between the left end of the ith shelf and its rightmost supporting peg in inches.

All shelves are situated on different heights and are properly supported by their pegs. The problem is guaranteed to have a solution for the input data.

输入文件的第一行包含四个整数数字 XN、 YN、 XT 和 YT,用空格分隔。相应地,它们是壁龛的宽度和高度,以英寸为单位的旧书的宽度和高度(1 < = XN,YN,XT,YT < = 1000)。输入文件的第二行包含一个整数 N (1 < = N < = 100) ,表示货架的数量。然后 N 行跟随。每一行代表一个单独的架子及其两个支撑柱,包含五个整数数字 yi,xi,li,x1i,x2i,用空格分隔,其中:

?yi(0 < yi < YN)-壁龛底部以上第四层的高度,以英寸为单位。

?Xi (0 < = xi < XN)-以英寸为单位的第四个架子左端与生态位左边缘之间的距离。

?Li (0 < li < = XN-xi)-以英寸为单位的第四个货架的长度。

?X1i (0 < = x1i < = li/2)-第四个架子的左端与最左边的支撑柱之间的距离,以英寸为单位。

?X2i (li/2 < = x2i < = li; x1i < x2i)-第四个架子左端与最右端支撑木桩之间的距离,以英寸为单位。

所有的架子都位于不同的高度,并由它们的钉子适当地支撑。这个问题保证对输入数据有一个解决方案。

输出
The output file shall contain two integer numbers separated by a space. The first one is the minimal number of pegs that are to be removed by Robinson from their original locations to place the tome. The second one is the minimal total length of planks in inches that are to be cut off during the redesign that removes the least number of pegs.

输出文件应该包含两个由空格分隔的整数。第一个是罗宾逊需要从原来的位置移除的最小数量的钉子来放置大部头。第二个是在重新设计过程中,以英寸为单位的木板的最小总长度,这些木板将在重新设计过程中被切断,从而去除最少的木钉。

样例输入
11 8 4 6
4
1 1 7 1 4
4 3 7 1 6
7 2 6 3 4
2 0 3 0 3
样例输出
1 3
来源
Northeastern Europe 2001


分析

先预处理所有的木板和高度,两个栓子的位置,以x来表示,最后排序一下。

然后依次从下往上枚举木板所在的高度,然后通过这块木板合法的左右移动,或者移动栓子来枚举这一高度所有的x位置

最后,在第二步的基础上,看看有没有上面的木板挡着这本古书,如果有,则用最小的花费来使得这个古书能放到这个位置。


代码
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
int Xn,Yn,Xt,YT,n;
struct node
{
	int h,x,len,l,r;
}P[105];
struct ANS
{
	int move,cut;
};
bool comp(node a,node  b)
{
	return a.h<b.h;
}
ANS _clear(int k,int p,int base)
{
	ANS t={0,0};t.move=base;
	//cout<<p<<" "<<base<<endl;
	//cout<<t.cut<<" "<<t.move<<endl;
	int a,b,c,d,e;
	int left=p,right=p+Xt;
	//cout<<endl;
	for(a=k+1;a<=n;a++)
	{
		
		if(P[a].h>=P[k].h+YT)break;
		int pos1=P[a].x;int pos2=P[a].x+P[a].len;
		if(pos1>=right||pos2<=left)continue;
		//cout<<t.cut<<" "<<endl; 
		if(P[a].r<=left)
		{
			if(P[a].len>left)
			{
				t.cut+=P[a].len-left;
				if(left-P[a].l<P[a].l)t.cut+=(2*P[a].l-left);
			}
			else
			{
				if(2*(left-P[a].l)<P[a].len)t.cut+=(P[a].len-2*(left-P[a].l));
			}
		}
		else if (P[a].l>=right)
		{
			if(P[a].len>Xn-right)
			{
				t.cut+=(P[a].len+right-Xn);
				if(P[a].r-right<Xn-P[a].r)t.cut+=(Xn+right-2*P[a].r);
			}
			else
			{
				if(2*(P[a].r-right)<P[a].len)t.cut+=(P[a].len-2*(P[a].r-right));
			}
		}
		else if(P[a].l<=left&&right<=P[a].r)
		{
			t.move++;
			if(left>=P[a].len)continue;
			if(Xn-right>=P[a].len)continue;
			if(left==0&&right==Xn)
			{
				t.move++;
				t.cut+=P[a].len;
				continue;
			}
			if(left==0)
			{
				t.cut+=(P[a].len-(Xn-right));
				continue;
			}
			if(right==Xn)
			{
				t.cut+=(P[a].len-left);
			    continue;
			}
			t.cut+=min((P[a].len-Xn+right),(P[a].len-left));
		}
		else if(P[a].l<=left&&left<=P[a].r&&P[a].r<=right)
		{
			t.move++;
			if(left>=P[a].len)continue;
			if(left==0)
			{
				t.move++;
				t.cut+=P[a].len;
			}
			else
			{
				t.cut+=(P[a].len-left);
			}
	    }
	    else if(left<=P[a].l&&P[a].l<=right&&right<=P[a].r)
	    {
	    	t.move++;
			if(Xn-right>=P[a].len)continue;
	    	if(right==Xn)
	    	{
	    		t.move++;
				t.cut+=P[a].len;
	    	}
	    	else
	    	{
	    		t.cut+=(P[a].len-Xn+right);
	    	}
	    }
	    else if(left<=P[a].l&&P[a].r<=right)
	    {
	    	t.move+=2;
	    	t.cut+=P[a].len;
	    }
	}
	//cout<<t.cut<<" "<<t.move<<" "<<k<<" "<<p<<endl;
	return t;
}
ANS _try(int k)
{
	ANS ans={999999999,999999999};
	if(P[k].len<Xt||P[k].h+YT>Yn)return ans;
	int a,b,c,d;
	//printf("%d %d\n",ans.cut,ans.move);
	for(a=0;a+Xt<=Xn;a++)
	{
		//cout<<a<<endl;
		ANS t;
		t.cut=0;t.move=0;
		if(a+P[k].len<P[k].l)continue;
		if(a+Xt-P[k].len>P[k].r)break;
		if(P[k].len>=(P[k].r-P[k].l)*2)
		{
			if((P[k].l-a)*2>P[k].len||(a+Xt-P[k].r)*2>P[k].len)t.move++;
		}
		else
		{
			if((P[k].r-a)>P[k].len||a+Xt-P[k].l>P[k].len)t.move++;
		}	
		t=_clear(k,a,t.move);	
		if(t.move<ans.move)ans=t;
		else if(t.move==ans.move&&t.cut<ans.cut)ans=t;
	}
	return ans;
}
int main()
{
	scanf("%d%d%d%d%d",&Xn,&Yn,&Xt,&YT,&n);
	int a,b,c,d,e;
	for(a=1;a<=n;a++)
	{
		scanf("%d%d%d%d%d",&P[a].h,&P[a].x,&P[a].len,&P[a].l,&P[a].r);
		P[a].l+=P[a].x;
		P[a].r+=P[a].x;
	}
	sort(P+1,P+n+1,comp);
	/*for(a=1;a<=n;a++)
	{
		printf("%d %d %d %d %d\n",P[a].h,P[a].x,P[a].len,P[a].l,P[a].r);;
	}*/
	ANS ans;ANS t;
	ans.move=999999999;ans.cut=999999999;
	for(a=1;a<=n;a++)
	{
		if(P[a].h+YT>Yn)break;
		t=_try(a);
		if(t.move<ans.move)ans=t;
		else if(t.move==ans.move&&t.cut<ans.cut)ans=t;
	}
	printf("%d %d",ans.move,ans.cut);
	return 0;
}

给个赞和关注吧

  • 30
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值