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;
}

 

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