POJ - 3347 Kadj Squares (思維)

鏈接:https://cn.vjudge.net/problem/POJ-3347

題意:給出n個正方形,把正方形按順序放進第一象限中並且正方形的兩底邊與x軸成45度角。儘可能讓正方形緊挨着放。問俯視時,最後哪幾個正方形不會被完全遮擋。

思路:如果所有邊長都擴大\sqrt2倍,那麼正方形的對角線也就是2倍的邊長,這樣就避免了精度問題。然後,每次放正方形(i)時,都遍歷一遍前面放好的正方形(j)。計算i與j正好相切時,i的最左邊的頂點的橫座標(即結構體力裏的l),最後取一個最大值。根據對角線的長度,算出i的最右邊的頂點的橫座標(即結構體力裏的r)。問題轉化爲求沒有被完全覆蓋的線段,對於本題,我們分別向前向後遍歷,把i被覆蓋的部分去掉,即改變i的l和r值,最後判斷l是否小於r即可。具體看圖,手殘,自己畫畫就懂了。

 

#include <cstdio>
#include <algorithm>
#include <cmath> 
#define ll long long
using namespace std; 
const int N = 100;
struct node
{
	int l,r,s;
}ls[N];
int n,ans[N],cnt;
int main(void)
{
	while(~scanf("%d",&n)&&n)
	{
		cnt=0;
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&ls[i].s);
			ls[i].l=0;
			for(int j=1;j<i;j++)
				ls[i].l=max(ls[i].l,ls[j].r-abs(ls[i].s-ls[j].s));		
			ls[i].r=ls[i].l+ls[i].s*2;
		}
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<i;j++)
				if(ls[i].s<ls[j].s&&ls[i].l<ls[j].r)
					ls[i].l=ls[j].r;
			for(int j=i+1;j<=n;j++)
				if(ls[i].s<ls[j].s&&ls[j].l<ls[i].r)
					ls[i].r=ls[j].l;		
		}
		for(int i=1;i<=n;i++)
			if(ls[i].l<ls[i].r)
				ans[++cnt]=i;
		for(int i=1;i<=cnt;i++)
			printf("%d%c",ans[i]," \n"[i==cnt]);	
	}
	
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章