POJ1231

这道题其实类似暴力、、、但是编了两次码都没过样例之后发现自己都想错了。

实际上只需要找出所有可能线段,然后对于每一个网格判断一下就可以了。

另外还有一种贪心地方法:

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

POJ1231的相关文章