洛谷P1105 平台 - C++

题目

在博客发现没有很详细的解题方案,于是就写了这第一篇题解。

思路及代码

首先我们常规操作

#include<iostream>
#include<cmath>
using namespace std;

既然标签给出了“模拟”,那我们就直接模拟到底,排序什么的都不用了

模拟二维空间,即建立二维数组,例如int map[20000][20000],二维数组其实很简单,不会的百度一下三分钟就学废了

为了方便查找第i个平台的高度,左端及右端,我们可以定义一个结构体,方便存储该序号的各项数值(h、l、r)。

struct plate
{
	int h,l,r;
}in[3000];//序号就不用再定义了,因为它就是数组的下标

接着,进入main函数,输入n。从1开始到n,输入in[i]。为什么从1开始呢,因为序号就是从1开始,所以这样更为方便。

为了节省时间,我们可以进行剪枝,例如存储最左与最右的下标(虽然说这样时间基本没有任何区别 )。在从map的该高度的l到r赋值为i,这样就算是标好序号了。

值得注意的是,我们需要判断map[h][j]是否有值,若有,就不赋值。毕竟如果有两个平台的高度相同且都可以被落到的话,那么会落到编号靠前的那个平台。这样,我们成功地渡过了输入阶段。

int n,maxn=-1,minn=999999;
cin>>n;
for(int i=1;i<=n;i++)
{
	cin>>in[i].h>>in[i].l>>in[i].r;
	maxn=max(maxn,in[i].r);
	minn=min(minn,in[i].l);	
    for(int x=in[i].l;x<=in[i].r;x++)
	{
		if(!map[in[i].h][x])
			map[in[i].h][x]=i;
	}
}

终于到达输出阶段了!但仍然不太简单,因为还有一个“搜索”的标签,这代表着我们需要一点点的简单搜索。没错,是特别无敌超级简单的搜索 。因为我们只需要在该纵轴上从上到下查找第一个出现的平台,再输出它的序号即可。

但是有两个问题:第一个问题就是落到另一个平台的边缘,是不算落在该平台上的;其次,平台可能会重叠,因此,我们搜索从上到下要从h-1的高度搜起。

这样,我们如果找到了平台就输出序号并跳出,否则就输出0。只需要左右两边分别考虑即可完成输出。

for(int i=1;i<=n;i++)
{
	int ll,rr;
	ll=in[i].l,rr=in[i].r;//用一个短的字符代替l和r,节省码量
	{
		if(ll<minn)
		{
			cout<<0;//特判,虽然作用不大
		}
		else
        {
       		for(int j=in[i].h-1;j>=1;j--)//从高到低
			{
			    if(map[j][ll])//若这是个平台
                {
                    if(&&ll!=in[map[j][ll]].l&&ll!=in[map[j][ll]].r)//避免落到平台边缘
    				{
	    				cout<<map[j][ll];
		   				goto herel;//输出该平台序号并跳出
		    		}
			    }
            }
			cout<<0;
			herel:;
		}
	}
	cout<<" ";
	{//基本相同,不解释
		if(rr>maxn)
		{
            cout<<0;
		}
		else
		{
			for(int j=in[i].h-1;j>=1;j--)
			{
				if(map[j][rr]&&rr!=in[map[j][rr]].l&&rr!=in[map[j][rr]].r)
				{
					cout<<map[j][rr];
					goto herer;
				}
			}
			cout<<0;
			herer:;
		}
	}
	cout<<endl;
}

点击提交,WA! 哇 !110分,妙啊(doge)。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值