【UOJ 452】钥匙挖墙
【题目描述】:
密闭的走廊四周都是水泥墙,只有一侧由近到远有着N+1个铁门(编号0至N),越越走进了唯一开着的0号铁门,拿到了一把钥匙和逃亡说明:“按照钥匙上数字ai的提示,前进或后退ai个铁门,然后打开对应的铁门,拿到里面的钥匙,直到打开N号铁门就可以逃出密室。”
越越刚鼓起勇气准备一个个的打开铁门,可是看了看走廊尽头他差点喷出一口鲜血,N<=1,000,000。一定还有其他的办法。越越走回0号房间坐在桌子上沉思……。还是没办法。越越气的拿脑袋撞墙:“碰碰……”。“等等”。
房间之间的墙是木板的,而且不是很厚,撞是撞不开的。越越举起手中大号的铜钥匙,钥匙没手柄,塞入钥匙孔就拿不出来了,但钥匙齿很锋利,用来锯一个让人穿过的孔还是可以的。钥匙锯开一个孔后磨损的也就不能用了。
看来越越除了拿钥匙按照顺序开门外,在第i个房间他还有另外两个选择,就是用钥匙挖通至i-1或i+1房间的墙。当然在0号房间挖墙只能向1号房间,N号房间就是出口。(一把钥匙可以用来开一扇门或者挖一堵木墙)
现在给你每扇门后钥匙上的数字,你能算出越越最少用掉几把钥匙才能走出这个恐怖的走廊吗?
【输入描述】:
第一行一个正整数数字N
第二行N个正整数顺序表示第0到第N-1扇门后钥匙上的数字。
【输出描述】:
输出越越需要开几扇门才能走出走廊。
【样例输入】:
10
5 9 4 6 4 -3 -5 -7 -5 -2
【样例输出】:
2
【样例说明】:
每个铁门上房间号: 0 1 2 3 4 5 6 7 8 9 10
房内钥匙上的数字: 5 9 4 6 4 -3 -5 -7 -5 -2
越越进房间的顺序: 0 1 2
【时间限制、数据范围及描述】:
时间:1s 空间:256M
对于 40%的数据:1<N<=1,000
对于100%的数据:1<N<=1,000,000
题解:我就是人间活脑瘫,摆着的最短路我都看不出来,我还在那写dp推式子推的一身劲,好家伙推了个0分
#include<cstdio> #include<iostream> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> #include<bits/stdc++.h> typedef long long ll; using namespace std; const int N=1000001; const int oo=0x3f3f3f3f; struct node{ int next; int to; }e[N*3]; int n,x,a[N],cnt,head[N],vis[N],dis[N]; void add(int x,int y){ e[++cnt].to=y; e[cnt].next=head[x]; head[x]=cnt; } queue<int>q; void spfa(){ memset(vis,0,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); q.push(0); vis[0]=1; dis[0]=0; while(!q.empty()){ int u=q.front(); vis[u]=0; q.pop(); for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(dis[v]>dis[u]+1){ dis[v]=dis[u]+1; if(!vis[v]){ vis[v]=1; q.push(v); } } } } } int main(){ freopen("452.in","r",stdin); freopen("452.out","w",stdout); scanf("%d %d",&n,&a[0]); add(0,a[0]); add(0,1); for(int i=1;i<n;i++){ scanf("%d",&a[i]); add(i,i-1); add(i,i+1); add(i,i+a[i]); } spfa(); printf("%d",dis[n]); return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步