题目描述
有n个大小不一的正方形,现将它们依次以45度斜放入第一象限,每个正方形都要与x轴有一个交点,且不能与之前放入的正方形重叠。在此前提下,正方形与x轴交点的坐标应尽可能小。问这样放置后,从上往下看,至少能部分被看见的正方形有哪些?
输入格式
每个测试点包含多组测试数据。每个测试数据的第一行是一个整数n,第二行是n个正整数,表示每个正方形的变长。输入以一行单独的0结束。
输出格式
对于每个测试数据输出一行,增序输出至少可看到部分的正方形的编号,用空格隔开。
样例输入
4
3 5 1 4
3
2 1 2
0
样例输出
1 2 4
1 3
注释
对于50%的数据,n<=10 ;
对于100%的数据,n<=50 正方形的大小不超过30。
分析
模拟放的过程,最后计算时,枚举寻找右边矩形左端点的最大值和左边矩形右端点的最小值,如果右边盖住左边,则被遮挡。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,s[51],a[51];
int main()
{ freopen("square.in","r",stdin);
freopen("square.out","w",stdout);
cin>>n;
while (n!=0)
{
memset(s,0,sizeof(a));
memset(a,0,sizeof(a));
cin>>a[1];
s[1]=a[1];
for (int i=2;i<=n;i++)
{
cin>>a[i];
s[i]=s[i-1]+2*min(a[i],a[i-1]);
for (int j=i-2;j>=1;j--)
{
if (s[i]-2*a[i] < s[j])
if (s[j]+2*a[j] > s[i])
s[i]=max(s[j]+2*min(a[j],a[i]),a[i]);
}
}
for (int i=1;i<=n;i++)
{
int le=s[n]+a[n],ri=0;
for (int j=1;j<i;j++) ri=max(ri,s[j]+a[j]);
for (int j=i+1;j<=n;j++) le=min(le,s[j]-a[j]);
if (le>ri) cout<<i<<" ";
}
cin>>n;
cout<<endl;
}
return 0;
}