POJ 3347 Kadj Squares

题意:给出n个正方形,一个挨着一个,求没有被其它正方形遮挡住的正方形有哪些

题解:看了DISCUSS 发现一个小技巧,就是把边长扩大根号2倍,那么输入的边长len 就是对角线的一半了。

然后两个步骤:

1.当前i,枚举之前的正方形,确定正方形的左边和右边。

方法是:首先,一个正方形的左边是取决于它和另外一个正方形 两者边更小的对角线长度的一半r,燃火这个“另外一个正方形”是前面求过的,用他的右端点坐标-r即为所求正方形的左端点。

写出公式来就是:a[i].l = max(a[i].l,a[j].r - abs( a[i].len - a[j].len ));

2.维护左端点和右端点,即枚举正方形i的左边正方形最多覆盖到哪,和枚举i右边的正方形最左覆盖到哪,如果a[i]<a[j]则这个正方形是满足的

代码:

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <algorithm>
 6 #include <queue>
 7 #include <cmath>
 8 using namespace std;
 9 struct node{
10         int l,r,len;
11 };
12 node a[60];
13 int main()
14 {
15        int n;
16        while(cin>>n)
17        {
18                memset(a,0,sizeof(a));
19                if(!n)break;
20                for(int i = 0;i < n; i++){
21                 cin>>a[i].len;
22                 a[i].l = 0;
23                 for(int j = 0;j<i;j++) a[i].l = max(a[i].l,a[j].r-abs(a[j].len-a[i].len));
24                 a[i].r = a[i].l + 2*a[i].len;
25                }
26                for(int i = 0;i < n; i++)
27                {
28                        for(int j = 0;j < i; j++)
29                                if(a[j].r>a[i].l && a[j].len > a[i].len)
30                                 a[i].l = a[j].r;
31                         for(int j = i+1;j < n; j++)
32                                 if(a[j].l<a[i].r && a[j].len > a[i].len)
33                                 a[i].r = a[j].l;
34                }
35                bool t = 1;
36                for(int i = 0;i < n;i ++)
37                {
38                        if(a[i].l<a[i].r)
39                        {
40                                if(t) t = false;
41                                else printf(" ");
42                                printf("%d",i+1);
43                        }
44                }
45                cout<<endl;
46 
47        }
48 }
View Code

 

posted on 2015-08-21 23:44  小松song  阅读(96)  评论(0)    收藏  举报

导航