现在有一列圆排在地平线上,用两个墙从左右向中间挤,问有哪些圆不会影响最终两个墙的距离
直接模拟做即可,另所有的圆尽量靠左,则在两相切的圆中间的那些不会影响最终两个墙的距离
最左边和最右边要特殊处理,最左边可以直接让圆不能超过左边的墙,最右边要判断,在圆的最右侧最靠右的圆里边的圆心最靠左的那个圆的右边的圆都是不会影响的
#include <cstdio>
#include <cstring>
#include <cmath>
const double eps=1e-9;
double r[1001];
double s[1001];
int last[1001];
int ans[1001];
int main() {
int n,i,j,ansn=0,rr=0,ri=0;
scanf("%d",&n);
for (i=0;i<n;i++) {
scanf("%lf",&r[i]);
if (i==0) {
s[i]=r[i];
last[i]=-1;
} else {
j=0;
s[i]=r[i];
last[i]=-1;
for (j=0;j<i;j++) {
double tmp=s[j]+sqrt((r[i]+r[j])*(r[i]+r[j])-(r[i]-r[j])*(r[i]-r[j]));
if (tmp-s[i]>eps) {
s[i]=tmp;
last[i]=j;
}
}
}
if (rr<s[i]+r[i]) {
rr=s[i]+r[i];
ri=i;
}
//printf("%d\n",last[i]);
}
for (i=n-1;i>ri;i--) {
ans[ansn++]=i;
}
for (i=ri;i>=0;i=last[i]) {
for (j=i-1;last[i]<j;j--) {
ans[ansn++]=j;
}
}
printf("%d\n",ansn);
for (i=ansn-1;i>=0;i--) printf("%d\n",ans[i]+1);
return 0;
}