UVA11343 Isolated Segments

題意:給了很多線段,點的座標都是整數,並且絕對值 <1000,如果某一條線段和其他任何一條線段都不想交,就是被隔離的,求出被隔離線段的個數

解題:每一條都去和剩下的線段判斷是否相交,只要相交就不是了,如果沒有和它相交的,被隔離的線段數就加一

WA:這是一個非常有意義的錯誤,而且不容易發現。題目給出的點的座標都是整數,而且都是小於1000,所以我放心的用INT,但是 向量的叉積就可能是1e6級別的,用INT會溢出,所以把求叉積的變量至少設爲double型纔可以。但是爲了完成判相等的操作,最好用long long int,浮點數判相等要用到abs(double) < eps。以後的編程過程中,不能簡單看輸入數據的類型和範圍,要考慮到每一個函數的結果可能的最大範圍。

代碼:

//uva11343  Isolated Segments
//AC By Warteac
//Runtime:0.019s
//2013-5-8
#include<iostream>
#include<cstdio>   
#include<vector>
#include<cstring>
using namespace std;  
struct point{  
    int x,y;  
    point(int x1 = 0, int y1 = 0){x = x1; y = y1;}  
    void print(){cout << "x= " << x << " y= " << y << endl;}  
 };//定義點結構體   
//求向量的叉積,p1*p2 > 0 => p1 在 p2的順時針方向,< 0 逆時針   
 long long direction(point pi,point pj,point pk){  
    return ((pj.x - pi.x)*(pk.y - pi.y)-(pk.x - pi.x)*(pj.y - pi.y));  
 }  
 //向量共線的前提下,判斷是點pk是否在線段(pi,pj)上   
 bool onSegment(point pi,point pj,point pk){  
    if( min(pi.x,pj.x) <= pk.x &&
        pk.x <= max(pi.x,pj.x) &&
        min(pi.y,pj.y) <= pk.y &&
        pk.y <= max(pi.y,pj.y) ){  
        return true;  
    }else{  
        return false;  
    }  
 }  
 //線段(p1,p2)和線段(p3,p4)是否相交   
 bool segmentsIntersect(point p1,point p2,point p3, point p4){  
    long long  d1,d2,d3,d4;  // int WA many times,double is not the best,long long is recommended
    d1 = direction(p3,p4,p1);  
    d2 = direction(p3,p4,p2);  
    d3 = direction(p1,p2,p3);  
    d4 = direction(p1,p2,p4);  
    //cout << d1 << " " << d2 <<" " << d3 << " " << d4 << endl; 
    if((d1*d2 < 0) && (d3*d4 < 0))  
        return true;  
    else if((d1 == 0)&&(onSegment(p3,p4,p1)))  
        return true;  
    else if((d2 == 0)&&(onSegment(p3,p4,p2)))  
        return true;  
    else if((d3 == 0)&&(onSegment(p1,p2,p3)))  
        return true;  
    else if((d4 == 0)&&(onSegment(p1,p2,p4)))  
        return true;  
    else return false;    
 }  
 int computing(vector <point> v ,int n){
     int r = 0,i,j;
     bool flag;
     for(i = 0; i < n; i++){
         //cout << "i = " << i << endl;   
         flag = false;
         for(j = 0; j < n; j++){ 
         //cout << "j = " << j << endl;   
         if(j == i) continue;
	         if(segmentsIntersect(v[2*i],v[2*i+1],v[2*j],v[2*j+1])){
	
	             flag = true;
	             break;
	         }
         }
         if(!flag)
            r++;
     }
     return r;
 }
 //////////////////////////////////////////////////
 int main(){
     int caseNum,x;
     cin >> caseNum;
     vector <point> vPoint;
     for(x = 0; x < caseNum; x++){
         int num;//num of segments
         cin >> num;
         int Xpi,Ypi,Xei,Yei;
         vPoint.clear();
         for(int i = 0; i < num; i++){
             cin >> Xpi >> Ypi >> Xei >> Yei;
             point p(Xpi,Ypi);
             vPoint.push_back(p);
             point q(Xei,Yei);
             vPoint.push_back(q);
         }    
         //cout <<"num = " << num << endl;
         cout << computing(vPoint,num) << endl ;
     }
     return 0;
 }

發佈了55 篇原創文章 · 獲贊 8 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章