信息学奥赛一本通:烦人的幻灯片(是真的烦人啊)

是真的烦人啊

题目:点击打开链接

样例的图片是长成这样的(真丑啊):


这张图大概就是样例;

当时有些同学可能没有读懂题,我其实是在读第二遍才读懂的;题目要求让你将每一个幻灯片与每一个点匹配,如果遇到有点与幻灯片无法匹配的情况,也就是当有多个幻灯片同时属于点x与点y,且无法确定到底是属于点x还是点y的,这就会造成无法匹配的情况,也就要输出“NO”。

为什么会造成不确定的情况呢,诶,因为我们在做题的时候是个瞎子啊——虽然点都是在幻灯片上的,但幻灯片透明且除了长宽高不同,其他都是一样的,所以单靠肉眼我们无法判断哪个点到底属于哪个幻灯片。但我们是有脑子的”狒狒“,我们事先知道每个幻灯片的长和宽,并且还知道每个点都不能够超过幻灯片的范围,所以仅仅靠着这两个条件,我们也许就可以确定每个点是属于哪一个幻灯片的了。

对于样例做小小的探究:

我们可以看到,4号“编号点”有且仅有一个幻灯片——“红幻灯片”与之对应,所以4号幻灯片就可以判断一定是属于“红幻灯片”的,即假设4号“编号点”不属于“红幻灯片”的话,它就只可能属于“空地”,然而这是不符合题意的,所以4号“编号点”必须属于“红幻灯片”!

根据前面的点我们就可以通过题意去判定某个点是否必须属于这个幻灯片,属于的话删掉这个幻灯片(因为我已经匹配了),就继续往下一个可以判定某个点的幻灯片;

我们可以用邻接链表来存储,但是因为这道题十分友好,所以考虑用vector来存储每个幻灯片也许可能匹配的点,因为vector成员函数可以直接调用v.size( )来判断吗,每张幻灯片可能对应的点的个数,若是1,则一定是匹配的!

下面是代码:

#include<bits/stdc++.h>
using namespace std;
const int N=10000+5;
int n,r[N],k,cn;
bool bd[N],bp[N];
struct wans{
	int xmin,xmax,ymin,ymax,idp;
}ppt[N];
struct lqx{
	int x,y,idd;
}dot[N];
struct out{
	char c;
	int num;
	bool operator < (const out &a) const {
		return c<a.c;
	}
}ans[N];
vector <lqx> v[N];
stack <lqx> s;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
	    cin>>ppt[i].xmin>>ppt[i].xmax>>ppt[i].ymin>>ppt[i].ymax;
		ppt[i].idp=i;
	}
	for(int i=1;i<=n;i++){
	    cin>>dot[i].x>>dot[i].y;
		dot[i].idd=i;
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++)
		    if(dot[j].x>=ppt[i].xmin && dot[j].x<=ppt[i].xmax && dot[j].y>=ppt[i].ymin && dot[j].y<=ppt[i].ymax){
		        v[i].push_back(dot[j]);
		        r[j]++;
		    }
	}
	for(int i=1;i<=n;i++)
	    if(r[dot[i].idd]==1)
	        s.push(dot[i]);
	while(!s.empty()){
		k++;
		lqx tmp=s.top();
		s.pop();
		
		for(int i=1;i<=n;i++)
		    if(tmp.x>=ppt[i].xmin && tmp.x<=ppt[i].xmax && tmp.y>=ppt[i].ymin && tmp.y<=ppt[i].ymax && bp[ppt[i].idp]==0){
		    	ans[++cn].c=(char)(ppt[i].idp-1+'A');ans[cn].num=tmp.idd;
				k=i;
				bp[ppt[i].idp]=1;
			}
		for(int i=0;i<v[k].size();i++){
			r[v[k][i].idd]--;
			if(r[v[k][i].idd]==1)
			    s.push(v[k][i]);
		}
	}
	if(k<n){
		cout<<"None";
		return 0;
	}
	sort(ans+1,ans+cn+1);
	for(int i=1;i<cn;i++)
	    cout<<ans[i].c<<" "<<ans[i].num<<endl;
	cout<<ans[cn].c<<" "<<ans[cn].num;
	return 0;
}
看着这代码,真的是比那幻灯片还“烦人了”哦!

加油咯!

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值