鏈接:https://cn.vjudge.net/problem/POJ-3347
題意:給出n個正方形,把正方形按順序放進第一象限中並且正方形的兩底邊與x軸成45度角。儘可能讓正方形緊挨着放。問俯視時,最後哪幾個正方形不會被完全遮擋。
思路:如果所有邊長都擴大倍,那麼正方形的對角線也就是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;
}