关卡一 洛谷比赛
题目背景
Lj终于弄懂了任务,他需要闯过九九八十一个关卡,才能拿到钥匙,回到主世界。为了早日回家,Lj踏入了第一关。这是一个由方块构成的世界,连Lj都被方块化了(MC?!)。
题目描述
构成这个世界的方块只有两种,泥土方块和栅栏方块。
由于这是第一关,管理员为了减少难度,将三维世界抽象成二维世界,并派遣NPC——Ljy去告诉Lj,他需要从起点通过跳跃到达终点。对于每次跳跃,他可以原地拔高h格,再水平移动g格。例如:他当前的高度为0,跳跃高度为2,跳跃长度为3,那么他就可以跳到之后3个位置中,高度不超过2的格子上(前提是他在跳跃过程不被挡住)
然而,坏坏的Ljy把某些泥土方块偷换成了栅栏方块(栅栏方块特性:你的最大跳跃高度加上你的高度必须大于栅栏方块的高度,但当你站在上面时,你的高度为栅栏方块的高度。举例:你的初始高度为0,跳跃高度为2,那么你只能跳到高度为0或1的栅栏方块上,而跳不上高度2的,但当你站在高度为2的栅栏方块上时,你的高度是2,而不是2.5或3)
规定:Lj一开始处在第0个方块的位置,高度为0
Lj想知道他能不能到达终点。
输入输出格式
输入格式:
第一行为一个正整数t,表示有t组数据
对于每组数据:
第一行为三个正整数n,h,g,表示有n个方块,Lj能垂直拔高的高度为h,Lj能水平移动的长度为g。
接下来n行由两个正整数qi,hi组成,qi为0,表示当前方块为泥土方块,qi为1,表示当前方块为栅栏方块,hi表示当前方块的高度。
输出格式:
对于每一个t有且仅有一个输出,Yes或No,Yes表示LJ能到达终点,No表示LJ无法到达终点。
输入输出样例
2 5 2 3 0 2 1 1 0 3 1 0 1 1 5 1 2 0 1 1 1 1 2 0 1 0 0
Yes No
说明
对于30%的数据,t=1,n≤10
对于60%的数据,t≤3,n≤1000
对于100%的数据,t≤10,n≤100000,hi≤200000,gi为0或1,h≤1000,g≤n
思路:
一个相当于DP的搜索模拟;
来,上代码:
#include<cstdio> #include<cstring> using namespace std; int t,n,h,g,type[100001],hight[100001]; char word; bool if_all,if_did[100001]; inline void read_int(int &now_1) { now_1=0,word=getchar(); while(word<'0'||word>'9') word=getchar(); while(word<='9'&&word>='0') { now_1=now_1*10+word-'0'; word=getchar(); } } void search(int now) { if(now>n) { if_all=true; return ; } if(if_did[now]) return; else if_did[now]=true; int can=now; for(int i=now+1;i<=now+g;i++) { if(i>n) { if_all=true; return ; } if(type[i]==1&&hight[now]+h>hight[i]) { can++; continue; } if(type[i]==0&&hight[now]+h>=hight[i]) { can++; continue; } break; } for(int i=can;i>now;i--) { search(i); if(if_all) return ; } } int main() { read_int(t); while(t--) { memset(if_did,false,sizeof(if_did)); if_all=false; read_int(n),read_int(h),read_int(g); for(int i=1;i<=n;i++) read_int(type[i]),read_int(hight[i]); search(0); if(if_all) printf("Yes\n"); else printf("No\n"); } return 0; }