POJ 3347 Kadj Squares
首先要确定的是每个正方形的位置,方法是这样的:当前放进来的正方形,和之前放好的每一个都算一遍紧贴的位置,取最大的那个就是当前正方形的位置。
接下来的问题就是几个区间先后放置,最终有几个区间看得见的问题了,可以用线段树,不过此题数据水,刷数组就0MS AC。
为了刷数组,坐标系都乘sqrt(2)倍,这样区间都是整数了。
#include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<algorithm> using namespace std; const int INF=0x7FFFFFFF; const int maxn=100; struct Square { int L,R; int S,B; int id; }f[maxn]; int n; int MaxR; int flag[10000000]; bool p[maxn]; int ans[maxn]; int tot; bool cmp(const Square&a,const Square&b) { return a.S<b.S; } int main() { while(~scanf("%d",&n)) { if(n==0) break; MaxR=-INF; memset(p,0,sizeof p); tot=0; for(int i=1;i<=n;i++) { scanf("%d",&f[i].S); f[i].id=i; } f[1].L=0; f[1].R=2*f[1].S; f[1].B=f[1].S; for(int i=2;i<=n;i++) { int MaxB=-1; for(int j=1;j<i;j++) { if(f[i].S<f[j].S){ if(f[j].B+2*f[i].S>MaxB) MaxB=f[j].B+2*f[i].S; } else if(f[i].S>=f[j].S) { double temp=f[j].B+2*f[j].S; if(temp-f[i].S<0) temp=f[i].S; if(temp>MaxB) MaxB=temp; } } f[i].B=MaxB; f[i].L=f[i].B-f[i].S; f[i].R=f[i].B+f[i].S; if(f[i].R>MaxR) MaxR=f[i].R; } sort(f+1,f+n+1,cmp); for(int i=1;i<=n;i++) for(int j=f[i].L;j<f[i].R;j++) flag[j]=f[i].id; for(int i=0;i<MaxR;i++) { if(p[flag[i]]==0) { ans[tot++]=flag[i]; p[flag[i]]=1; } } sort(ans,ans+tot); for(int i=0;i<tot;i++) { printf("%d",ans[i]); if(i<tot-1) printf(" "); else printf("\n"); } } return 0; }