【做题笔记】SP5463 BIRD - Bird or not bird

Problem

SP5463 BIRD - Bird or not bird

题目大意:

已知若一只动物是鸟,则它的身高在一个区间内,体重在另一个区间内。且若一只动物的身高和体重都在相应的区间内,则它一定是鸟。

给你 \(n\) 只动物的身高和体重并告诉你它们是不是鸟。

然后又给你 \(m\) 只动物的身高和体重,请你回答它们是不是鸟,或者回答你不能确定它们是不是鸟。

Solution

对于那 \(n\) 只动物,显然可以对是鸟的和不是鸟的分开处理,身高和体重分开处理。

对于是鸟的:

对于身高,取一个最大值和一个最小值,构成已知的鸟的身高区间。体重也一样。

对于不是鸟的:

若其中一个值(这里以体重为例)在鸟的区间中,则另一个值(身高)一定不在鸟的区间中。在满足条件的所有数据中,取一个最大身高,它比鸟的身高区间的最小值还要小。再取一个最小身高,它比鸟的身高区间的最大值还要大。

于是对于身高和体重,都会变成下面这种情况:

但是!在不是鸟的动物中,如果身高体重没有一个满足在鸟的区间内,这些动物还没有被使用过。

假设有一个满足上面条件的动物 \(i\),它的身高和体重分别为 \(h_i,w_i\)
另有一个待判断的动物 \(j\),它的身高和体重分别为 \(h_j,w_j\),且已经判定它要么是 NOT BIRD,要么是 UNKNOWN
设已知的鸟的身高区间为 \([HL,HR]\),体重区间为 \([WL,WR]\)
如果它们满足如下两种情况:

  • \(h_j \le h_i < HL\)\(h_j \ge h_i > HR\)
  • \(w_j \le w_i < WL\)\(w_j \ge w_i > WR\)

可不可以判定它是 NOT BIRD?可以。因为已知 \(i\) 要么身高不符合要求,要么体重不符合要求,且无论 \(i\) 是身高不符合要求还是体重不符合要求,最终都可以推断出 \(j\) 不是鸟。

另外还有一个注意点,如果给的 \(n\) 只动物中没有 BIRD,那么对于询问,判断一下身高体重与前 \(n\) 只动物有没有完全相同的,有则 NOT BIRD,否则为 UNKNOWN。(虽然直接输出 UNKNOWN 也能对(雾))

Code

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int T,n,m,cnt,h[1005],w[1005];
//h,w 为前 n 只动物中 NOT BIRD 的动物的身高和体重,cnt 为它们的数量。
int bhl,bhr,bwl,bwr,nhr,nhl,nwr,nwl;
//[bhl,bhr] 为可以确定的鸟的身高区间。
//[bwl,bwr] 为可以确定的鸟的体重区间。
//nhr 为身高中左边的 NOTBIRD 的最大值。
//nhl 为身高中右边的 NOTBIRD 的最小值。
//nwr 为体重中左边的 NOTBIRD 的最大值。
//nwl 为体重中右边的 NOTBIRD 的最小值。
int num,H[1005],W[1005];
//H,W 为身高和体重都不在[bhl,bhr],[bwl,bwr] 中的鸟的身高和体重,num为它们的数量。
int main()
{
	scanf("%d",&T);
	for(int Case=1;Case<=T;Case++)
	{
		scanf("%d",&n);cnt=0;
		bhl=bwl=nhl=nwl=1e6+1;bhr=bwr=nhr=nwr=0;
		for(int i=1;i<=n;i++)
		{
			int hh,ww;
			scanf("%d%d",&hh,&ww);
			string s;
			cin>>s;
			if(s=="BIRD")
			{
				bhl=min(bhl,hh);
				bhr=max(bhr,hh);
				bwl=min(bwl,ww);
				bwr=max(bwr,ww);
                //以上为求 bhl,bhr,bwl,bwr。
			}
			else{cin>>s;cnt++;h[cnt]=hh,w[cnt]=ww;}
		}
		num=0;
		for(int i=1;i<=cnt;i++)
		{
			int flag=0;
			if(h[i]<bhl&&bwl<=w[i]&&w[i]<=bwr) nhr=max(nhr,h[i]),flag=1;
			if(h[i]>bhl&&bwl<=w[i]&&w[i]<=bwr) nhl=min(nhl,h[i]),flag=1;
			if(w[i]<bwl&&bhl<=h[i]&&h[i]<=bhr) nwr=max(nwr,w[i]),flag=1;
			if(w[i]>bwl&&bhl<=h[i]&&h[i]<=bhr) nwl=min(nwl,w[i]),flag=1;
            //以上为求nhr,nhl,nwr,nwl。
			if(!flag){num++;H[num]=h[i];W[num]=w[i];}
		}
		printf("Case #%d:\n",Case);
		scanf("%d",&m);
		for(int i=1;i<=m;i++)
		{
			int qh,qw;
			scanf("%d%d",&qh,&qw);
			if(cnt!=n)
			{
				if(bhl<=qh&&qh<=bhr&&bwl<=qw&&qw<=bwr) puts("BIRD");
				else if(qh<=nhr||qh>=nhl||qw<=nwr||qw>=nwl) puts("NOT BIRD");
				else
				{
					for(int i=1;i<=num;i++)
					{
						int f1=(H[i]<=bhl)?(qh<=H[i]):(qh>=H[i]);
						int f2=(W[i]<=bwl)?(qw<=W[i]):(qw>=W[i]);
						if(f1&&f2){puts("NOT BIRD");goto FINISH;}
					}
                    //以上为另一种 NOT BIRD 的情况。
					puts("UNKNOWN");
					FINISH:;
				}
			}
			else//前 n 只动物中没有 BIRD。
			{
				for(int j=1;j<=n;j++)
					if(qh==h[j]&&qw==w[j]){puts("NOT BIRD");goto END;}
				puts("UNKNOWN");
				END:;
			}
		}
	}
	return 0;
}
posted @ 2022-02-08 14:38  Mine_King  阅读(46)  评论(0编辑  收藏  举报