一個正方形的古老墓園,有n面墻,墻的端點都在正方形的邊上。已知墓碑的地點(x,y),問從外面一直到達(dá)墓碑至少要鑿開幾個門,而且規(guī)定門只能鑿在當(dāng)前點段的中點。 思路很巧妙,因為從一個點到終點不可能“繞過”圍墻,只能傳過去,所以門是否開在中點是無所謂
一個正方形的古老墓園,有n面墻,墻的端點都在正方形的邊上。已知墓碑的地點(x,y),問從外面一直到達(dá)墓碑至少要鑿開幾個門,而且規(guī)定門只能鑿在當(dāng)前點段的中點。
思路很巧妙,因為從一個點到終點不可能“繞過”圍墻,只能傳過去,所以門是否開在中點是無所謂的,只要求四周線段中點到終點的線段與墻的最少交點個數(shù)即可。更進(jìn)一步,實際上,只需判斷四周圍墻的所有點與終點的連線與內(nèi)墻的最少交點加一即可。
const double eps = 1e-8 ; double add(double x , double y){ if(fabs(x+y) < eps*(fabs(x) + fabs(y))) return 0 ; return x + y ; } struct Point{ double x , y ; Point(){} Point(double _x , double _y):x(_x),y(_y){} Point operator + (Point o){ return Point(add(x , o.x) , add(y , o.y)) ; } Point operator - (Point o){ return Point(add(x , -o.x) , add(y , -o.y)) ; } Point operator * (double o){ return Point(x*o , y*o) ; } double operator ^(Point o){ return add(x*o.y , -y*o.x) ; } double dist(Point o){ return sqrt((x-o.x)*(x-o.x) + (y-o.y)*(y-o.y)) ; } void read(){ scanf("%lf%lf" ,&x , &y) ; } }; int interdiv(Point p1 , Point p2 , Point q1 , Point q2){ double d1 = (p2 - p1) ^ (q1 - p1) ; double d2 = (p2 - p1) ^ (q2 - p1) ; double d3 = (q2 - q1) ^ (p1 - q1) ; double d4 = (q2 - q1) ^ (p2 - q1) ; return d1 * d2 < 0 && d3 * d4 < 0 ; } struct Line{ Point s , t ; Line(){} Line(Point _s , Point _t):s(_s),t(_t){} int intersect(Line o){ // 直線與線段O是否相交 return interdiv(s , t , o.s , o.t) ; } void read(){ s.read() , t.read() ; } friend bool operator < (const Line A ,const Line B){ return A.s.x < B.s.x ; } }; vectorlisline ; vector lispoint ; int main(){ int t , k , n , i , j , T = 1 ; Point ed , ls , ld ; cin>>t ; while(t--){ cin>>n ; lispoint.clear() ; lisline.clear() ; lispoint.push_back(Point(0.0 , 0.0)) ; lispoint.push_back(Point(0.0 , 100.0)) ; lispoint.push_back(Point(100.0 , 0.0)) ; lispoint.push_back(Point(100.0 , 100.0)) ; for(i = 1 ; i <= n ; i++){ ls.read() , ld.read() ; lispoint.push_back(ls) ; lispoint.push_back(ld) ; lisline.push_back(Line(ls , ld)) ; } ed.read() ; int ans = 100000000 , sum ; for(i = 0 ; i < lispoint.size() ; i++){ Line now = Line(lispoint[i] , ed) ; sum = 0 ; for(j = 0 ; j < lisline.size() ; j++){ if(now.intersect(lisline[j])) sum++ ; } ans = min(ans , sum) ; } if(T != 1) puts("") ; T++ ; printf("Number of doors = %d\n" , ans+1) ; } return 0 ; }
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com