首页 > 代码库 > poj 1066 Treasure Hunt
poj 1066 Treasure Hunt
http://poj.org/problem?id=1066
大意; 问在房间中有一份宝藏,但是房间中有一些隔板,问最少需要通过多少隔板
思路: 链接宝藏与爆破地点,枚举每一条直线寻找最少破坏的隔板。。
1 #include <iostream> 2 #include <algorithm> 3 #include <cmath> 4 using namespace std; 5 const int maxn = 110; 6 const double eps = 1e-8; 7 8 double fix_double(double x){ 9 return fabs(x)<eps?0.0:x; 10 } 11 12 int sign(double x){ 13 return x<-eps?-1:x>eps; 14 } 15 16 struct point { 17 double x,y; 18 //point (){} 19 point(double x=0,double y=0):x(x),y(y){} 20 point operator - (const point b) const { 21 return point(x-b.x,y-b.y); 22 } 23 }; 24 25 struct line { 26 point a,b; 27 line(){} 28 line(point _a,point _b){ 29 a = _a; 30 b = _b; 31 } 32 }; 33 double dot(point o,point a,point b){ 34 point oa = a-o; 35 point ob = b-o; 36 return oa.x*ob.x+oa.y*ob.y; 37 } 38 39 double cross(point o,point a,point b){ 40 point oa = a-o; 41 point ob = b-o; 42 return oa.x*ob.y-ob.x*oa.y; 43 } 44 45 int n; 46 line ln[maxn]; 47 point tr,pt[maxn*10];//tr为宝藏,pt为边上的点 48 49 double dis(point a,point b){ 50 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 51 } 52 53 bool cmp(point a,point b){ //数据太弱这样也过了。。。 54 point zero = point(0,0); 55 int ans = sign(cross(zero,a,b)); 56 if(ans==0) return dis(zero,a)+eps<dis(zero,b); 57 return ans>0; 58 } 59 //0不在,1,在线段内,2在断点处 60 int in_line(point pt, line li){ 61 if(sign(cross(pt,li.a,li.b))) return 0; 62 int ans = sign(dot(pt,li.a,li.b)); 63 return ans==0?2:ans<0;//cos钝角小于0.。 64 } 65 66 //0不相交,1规范相交,2交与短点,3,有重合部分 67 int across(line ab,line cd){ 68 if(max(ab.a.x,ab.b.x)<min(cd.a.x,cd.b.x)||max(ab.a.y,ab.b.y)<min(cd.a.y,cd.b.y)||max(cd.a.x,cd.b.x)<min(ab.a.x,ab.b.x)||max(cd.a.y,cd.b.y)<min(ab.a.y,ab.b.y)) 69 return 0; 70 int ab_cd = sign(cross(ab.a,ab.b,cd.a))*sign(cross(ab.a,ab.b,cd.b)); 71 int cd_ab = sign(cross(cd.a,cd.b,ab.a))*sign(cross(cd.a,cd.b,ab.b)); 72 if(ab_cd==0&&cd_ab==0&&(in_line(ab.a,cd)==1||in_line(ab.b,cd)==1)) 73 return 3; 74 if(ab_cd<0) 75 return cd_ab==0?2:cd_ab<0; 76 else if(ab_cd==0) 77 return cd_ab<=0?2:0; 78 return 0; 79 } 80 81 int solve(){ 82 int ans = 0x3f3f3f3f,cnt=0; 83 for(int i=0;i<n;i++){ 84 pt[cnt++] = ln[i].a; 85 pt[cnt++] = ln[i].b; 86 } 87 pt[cnt++] = point(0,0); 88 pt[cnt++] = point(0,100); 89 pt[cnt++] = point(100,0); 90 pt[cnt++] = point(100,100); 91 sort(pt,pt+cnt,cmp); 92 for(int i=1;i<cnt;i++){ 93 point cn = point((pt[i].x+pt[i-1].x)/2,(pt[i].y+pt[i-1].y)/2); 94 line lt = line(tr,cn); 95 int tot=0; 96 for(int j=0;j<n;j++){ 97 if(across(lt,ln[j])) tot++; 98 } 99 if(tot<ans) ans = tot; 100 } 101 return ans+1; 102 } 103 int main() 104 { 105 while(cin>>n){ 106 for(int i=0;i<n;i++){ 107 cin>>ln[i].a.x>>ln[i].a.y>>ln[i].b.x>>ln[i].b.y; 108 } 109 cin>>tr.x>>tr.y; 110 int res = solve(); 111 cout<<"Number of doors = "<<res<<endl; 112 } 113 return 0; 114 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。