题意:n个正方形,要求45°角放置,最左边的正方形紧贴Y轴,所有的正方形的下面的端点都在X轴上。然后按照正方形不能交错但要尽可能的挨着的原则,摆放,最后输出从上往下看能看到的正方形的编号。
思路:
先把给定的边长看作/根号2后的结果,则原始长度为正方形的对角线长度。
求每个正方形在X轴的位置,
p
[
i
]
=
m
i
n
(
p
[
j
]
+
m
i
n
(
s
[
i
]
,
s
[
j
]
)
)
p[i] = min(p[j] + min(s[i], s[j]))
p[i]=min(p[j]+min(s[i],s[j]))
对每一个正方形,判断是否被全覆盖。仅有长度大于它的正方形有可能覆盖它,且不存在覆盖它中间一段的情况。
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<list>
#include<stack>
#include<queue>
#include<vector>
#define cl (k<<1)
#define cr (k<<1|1)
#define Mid ((a[k].l+a[k].r)>>1)
#define mem(a,x) memset(a,x,sizeof(a))
using namespace std;
#define bug printf("???\n")
typedef long long LL;
const int Inf=0x3f3f3f3f;
const double eps=1e-7;
const int maxn=150;
double s[maxn];
double p[maxn];
int vis[maxn];
int main()
{
int n;
while(cin>>n, n){
for(int i=1; i<=n; i++){
scanf("%lf",&s[i]); //设s[i]为对角线长度,即乘以根2
}
for(int i=1; i<=n; i++){
p[i] = s[i]/2;
for(int j=1; j<i; j++){
p[i] = max(p[i], p[j]+min(s[i], s[j]));
}
// printf("%.2lf\n",p[i]);
}
mem(vis, 0); //0 看得见
for(int i=1; i<=n; i++){
double l=p[i]-s[i]/2, r=p[i]+s[i]/2;
for(int j=1; j<=n; j++){
if(s[j]>s[i]){
double l0=p[j]-s[j]/2, r0=p[j]+s[j]/2;
if(l0<=l&&l<=r0){
l = r0;
}
if(l0<=r&&r<=r0){
r = l0;
}
}
}
if(l>r) vis[i] = 1;
}
for(int i=1; i<=n; i++){
if(vis[i]==0){
printf("%d ",i);
}
}
printf("\n");
}
}