/*
题意:给出一些字母的坐标,是否能把相同的字母放到同一个矩形中,使每个矩形都不重合,重合一个点也不行
2 两组数据
3 2 K,P,K个字母,每个字母有P个坐标
6 4 8 4
4 2 2 1
2 3 2 4
如果两个矩形映射到x轴和y轴上都都有重合的,那么他们就有重合的
1. 对于同一种字母,求出它出现位置的最左边、最右边、最上边、最下边。这就构成了一个矩形。
2. 对于在x轴上投影重合的一系列矩形,他们必定处在同一个方格内。给这些方格编号。
3. 对于在y轴上投影重合的一系列矩形,如果其中两个编号相同,就不符合条件了。
*/
#include<stdio.h>
#include<algorithm>
using namespace std;
int K,P;
struct node
{
int left,right,top,bootom;
int rank_x;
} a[30];
bool cmp_x(node p,node q)
{
return p.left<q.left;
}
bool cmp_y(node p,node q)
{
return p.top<q.top;
}
int Max(int aa,int bb)
{
return aa>bb?aa:bb;
}
int ok()
{
sort(a,a+K,cmp_x);//把每个字母的矩形按左边的下标排序,所以映射到x轴上相重合的一定相邻
int rank=0,i,last,mas;
for(i=0; i<K; )//注意没有i++
{
last=a[i].right;//记录相重合的的矩形最右边的坐标
while(i<K&&a[i].left<=last)//顺次遍历每个字母的矩形左右坐标映射到图中x轴上
{
a[i].rank_x=rank;
last=Max(a[i].right,last);
i++;
}
rank++;
}
sort(a,a+K,cmp_y);//按照矩形的上坐标从小到大排序,所以映射到y轴上,相重合的一定相邻
for(i=0; i<K;)
{
mas=0;//每次有不重合的矩形时,mas都初始化0,记录的1<<rank_x出现过没有
last=a[i].bootom;
while(i<K&&a[i].top<=last)
{
if(mas&1<<a[i].rank_x)//因为当1<<a[i].rank_x没出现过时,按位&的结果是0,否则为1,为1时说明映射到x轴,y轴都有重合
return 0;
mas|=1<<a[i].rank_x;//因为1<<a[i].rank_x的二进制串中肯定只有最高位是1其他的都是0按位或之后就把
last=Max(a[i].bootom,last);//mas中对应的哪一位变成1,相当于记录下来了,a[i].rank_x是否出现过
i++;
}
}
return 1;
}
int main()
{
int t,i,j,x,y;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&K,&P);
for(i=0; i<K; i++)
{
a[i].left=a[i].top=999999999;//最每个字母所形成的的矩形进行初始化
a[i].right=a[i].bootom=0;
for(j=0; j<P; j++)
{
scanf("%d%d",&x,&y);
if(x<a[i].left)//更新矩形最左边的坐标
a[i].left=x;
if(x>a[i].right)//更新矩形最右边的坐标
a[i].right=x;
if(y<a[i].top)//更新最上边的坐标
a[i].top=y;
if(y>a[i].bootom)//更新矩形最下边的坐标
a[i].bootom=y;
}
}
int aa=ok();
if(aa)
puts("YES");
else
puts("NO");
}
return 0;
}
题意:给出一些字母的坐标,是否能把相同的字母放到同一个矩形中,使每个矩形都不重合,重合一个点也不行
2 两组数据
3 2 K,P,K个字母,每个字母有P个坐标
6 4 8 4
4 2 2 1
2 3 2 4
如果两个矩形映射到x轴和y轴上都都有重合的,那么他们就有重合的
1. 对于同一种字母,求出它出现位置的最左边、最右边、最上边、最下边。这就构成了一个矩形。
2. 对于在x轴上投影重合的一系列矩形,他们必定处在同一个方格内。给这些方格编号。
3. 对于在y轴上投影重合的一系列矩形,如果其中两个编号相同,就不符合条件了。
*/
#include<stdio.h>
#include<algorithm>
using namespace std;
int K,P;
struct node
{
int left,right,top,bootom;
int rank_x;
} a[30];
bool cmp_x(node p,node q)
{
return p.left<q.left;
}
bool cmp_y(node p,node q)
{
return p.top<q.top;
}
int Max(int aa,int bb)
{
return aa>bb?aa:bb;
}
int ok()
{
sort(a,a+K,cmp_x);//把每个字母的矩形按左边的下标排序,所以映射到x轴上相重合的一定相邻
int rank=0,i,last,mas;
for(i=0; i<K; )//注意没有i++
{
last=a[i].right;//记录相重合的的矩形最右边的坐标
while(i<K&&a[i].left<=last)//顺次遍历每个字母的矩形左右坐标映射到图中x轴上
{
a[i].rank_x=rank;
last=Max(a[i].right,last);
i++;
}
rank++;
}
sort(a,a+K,cmp_y);//按照矩形的上坐标从小到大排序,所以映射到y轴上,相重合的一定相邻
for(i=0; i<K;)
{
mas=0;//每次有不重合的矩形时,mas都初始化0,记录的1<<rank_x出现过没有
last=a[i].bootom;
while(i<K&&a[i].top<=last)
{
if(mas&1<<a[i].rank_x)//因为当1<<a[i].rank_x没出现过时,按位&的结果是0,否则为1,为1时说明映射到x轴,y轴都有重合
return 0;
mas|=1<<a[i].rank_x;//因为1<<a[i].rank_x的二进制串中肯定只有最高位是1其他的都是0按位或之后就把
last=Max(a[i].bootom,last);//mas中对应的哪一位变成1,相当于记录下来了,a[i].rank_x是否出现过
i++;
}
}
return 1;
}
int main()
{
int t,i,j,x,y;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&K,&P);
for(i=0; i<K; i++)
{
a[i].left=a[i].top=999999999;//最每个字母所形成的的矩形进行初始化
a[i].right=a[i].bootom=0;
for(j=0; j<P; j++)
{
scanf("%d%d",&x,&y);
if(x<a[i].left)//更新矩形最左边的坐标
a[i].left=x;
if(x>a[i].right)//更新矩形最右边的坐标
a[i].right=x;
if(y<a[i].top)//更新最上边的坐标
a[i].top=y;
if(y>a[i].bootom)//更新矩形最下边的坐标
a[i].bootom=y;
}
}
int aa=ok();
if(aa)
puts("YES");
else
puts("NO");
}
return 0;
}