这道题其实类似暴力、、、但是编了两次码都没过样例之后发现自己都想错了。
实际上只需要找出所有可能线段,然后对于每一个网格判断一下就可以了。
另外还有一种贪心地方法:
1. 对于同一种字母,求出它出现位置的最左边、最右边、最上边、最下边。这就构成了一个矩形。
2. 对于在x轴上投影重合的一系列矩形,他们必定处在同一个方格内。给这些方格编号。
3. 对于在y轴上投影重合的一系列矩形,如果其中两个编号相同,就不符合条件了。
1 /************************** 2 POJ 1231 3 716K 4 0MS 5 2015-06-27 6 By JimmyLin 7 **************************/ 8 #include<iostream> 9 #include<cstdio> 10 #include<string> 11 #include<cstring> 12 #include<algorithm> 13 14 using namespace std; 15 const int maxn=100; 16 const int INF=maxn+1; 17 int maxx[maxn],minx[maxn],maxy[maxn],miny[maxn]; 18 int xx[maxn],yy[maxn],xxnum,yynum; 19 int k,p; 20 bool checkx(int ll) 21 { 22 for(int i=1;i<=k;i++) 23 if(ll>=minx[i]&&ll<maxx[i])return false; 24 return true; 25 } 26 bool checky(int ll) 27 { 28 for(int i=1;i<=k;i++) 29 if(ll>=miny[i]&&ll<maxy[i])return false; 30 return true; 31 } 32 void check(int ll,int xy) 33 { 34 if(xy==0&&checkx(ll))xx[xxnum++]=ll; 35 if(xy==1&&checky(ll))yy[yynum++]=ll; 36 } 37 bool everythingok() 38 { 39 for(int i=0;i<xxnum-1;i++) 40 for(int j=0;j<yynum-1;j++){ 41 int tot=0; 42 for(int q=1;q<=k;q++)if(minx[q]-1>=xx[i]&&maxx[q]<=xx[i+1]&&miny[q]-1>=yy[j]&&maxy[q]<=yy[j+1])tot++; 43 if(tot>=2)return false; 44 } 45 return true; 46 } 47 int main() 48 { 49 int kase; 50 cin>>kase; 51 while(kase--){ 52 xxnum=0;yynum=0; 53 memset(xx,0,sizeof(xx)); 54 memset(yy,0,sizeof(yy)); 55 memset(maxx,0,sizeof(maxx)); 56 memset(minx,0x3f,sizeof(minx)); 57 memset(maxy,0,sizeof(maxy)); 58 memset(miny,0x3f,sizeof(miny)); 59 cin>>k>>p; 60 for(int i=1;i<=k;i++){ 61 int xx,yy; 62 for(int j=1;j<=p;j++){ 63 cin>>xx>>yy; 64 maxx[i]=max(maxx[i],xx); 65 maxy[i]=max(maxy[i],yy); 66 minx[i]=min(minx[i],xx); 67 miny[i]=min(miny[i],yy); 68 } 69 } 70 for(int i=1;i<=k;i++){ 71 check(maxx[i],0); 72 check(maxy[i],1); 73 check(minx[i]-1,0); 74 check(miny[i]-1,1); 75 } 76 sort(xx,xx+xxnum); 77 sort(yy,yy+yynum); 78 if(everythingok())cout<<"YES"<<endl; 79 else cout<<"NO"<<endl; 80 } 81 return 0; 82 }
时间: 2024-11-05 23:02:44