一个简单的题;
感觉像计算几何,其实并用不到什么计算几何的知识;
方法:
首先对每条边判断一下,看他们能够把平面分成多少份;
然后用边来对点划分集合,首先初始化为一个集合;
最后如果点的集合等于平面的份数,就说明每块都有一个士兵;
代码:
1 #include<cstdio> 2 #include<vector> 3 #define maxn 105 4 #define maxm 50005 5 using namespace std; 6 int a[maxn],b[maxn],c[maxn]; 7 long long x[maxm],y[maxm]; 8 int main() 9 { 10 int t,n,m; 11 scanf("%d",&t); 12 while(t--) 13 { 14 scanf("%d%d",&n,&m); 15 for(int i=0; i<n; i++) 16 scanf("%d%d%d",&a[i],&b[i],&c[i]); 17 for(int i=0; i<m; i++) 18 scanf("%lld%lld",&x[i],&y[i]); 19 int cnt=1; 20 for(int i=0; i<n; i++) 21 { 22 cnt++; 23 for(int j=0; j<i; j++) 24 { 25 if(a[i]*b[j]!=a[j]*b[i]) 26 cnt++; 27 } 28 } 29 vector< vector<int> >ve; 30 ve.resize(1); 31 for(int i=0; i<m; i++)ve[0].push_back(i); 32 for(int i=0; i<n; i++) 33 { 34 int l=ve.size(); 35 for(int j=0; j<l; j++) 36 { 37 vector<int>vv[2]; 38 int si=ve[j].size(); 39 for(int k=0; k<si; k++) 40 { 41 int v=ve[j][k]; 42 if(x[v]*a[i]+y[v]*b[i]+c[i]<0) 43 vv[0].push_back(v); 44 else vv[1].push_back(v); 45 } 46 if(vv[0].empty())swap(vv[0],vv[1]); 47 ve[j]=vv[0]; 48 if(!vv[1].empty()) ve.push_back(vv[1]); 49 } 50 } 51 if(cnt==ve.size())puts("PROTECTED"); 52 else puts("VULNERABLE"); 53 } 54 return 0; 55 }