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 }
浙公网安备 33010602011771号