在博客发现没有很详细的解题方案,于是就写了这第一篇题解。
思路及代码
首先我们常规操作
#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)。