HAUTOJ 玲珑杯 爱看电视的LsF(BFS)


1269: 爱看电视的LsF

时间限制: 1 秒  内存限制: 64 MB
提交: 185  解决: 39
提交  状态 
题目描述

LsF(刘师傅)非常喜欢看电视!
不幸的是,遥控器上的一些数字按钮坏了。 但他灵光一闪,如果他不能直接输入他想要看到的频道的号码,那么他可以先输入其他号码,再通过按下按钮+ 和- (这两个按钮由24K钛合金制成,永远不会坏)的方式到达所需的频道。 按钮+将数字增加1,按钮-将数字减少1。当然他依然可以使用那些完好无损的数字按钮输入号码。
他最初在第S频道,他想看第T频道。他想知道由ST频道所需的最少按钮按压次数。

输入

输入包含多组数据。
对于每组数据,第一行是三个整数n,S,T(n≤10,0≤S,T≤500,000。 第二行是n个数字 a1,a2,...,an,表示数字 ai键已经坏了(0≤ai≤9,aiaj when ij)。

输出

输入包含多组数据。
对于每组数据,第一行是三个整数n,S,T(n≤10,0≤S,T≤500,000。 第二行是n个数字 a1,a2,...,an,表示数字 ai键已经坏了(0≤ai≤9,aiaj when ij)。

样例输入
10 1 1000 1 2 3 4 5 6 7 8 99 1 1000 1 2 3 4 5 6 7 8
样例输出
993
提示
来源

提交  状态 

题目链接

因为处理yu()函数中0的时候忘记让key=1而错,很可惜QAQ


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
struct po{
	int x,time;
};
int num[10]; 
int a[11];  //用bool型表示0~9哪几个按钮坏了,坏了标记为1 
int map[500000];  //标记已搜索过的点 
int dir[2]={-1,1};//两个方向BFS 
int key; //直接按数字按钮到某个频道要按多少次 
int yu(int t){  //判断t是否能直接被数字键按出 
	int i,j,tt=t,k;
	j=0;
	if(tt==0){
		if(a[0]) return 0;
		else {
			key=1;return 1;
		}
	}
	while(tt>0){
		num[j]=tt%10;
		tt/=10;
		j++;
	}
	key=0;
	for(i=0;i<j;i++){
		if(a[num[i]]) return 0;
		key++;
	}
	return 1;
}
void bfs(po p,int len){
	int i;
	queue<po>que;
	que.push(p);
	po hd;
	if(yu(p.x)){  //判断起始点是否能直接被按出
		p.time+=key;
		if(p.time>=len){
			printf("%d\n",len);
			return ;
		}				
		printf("%d\n",p.time);
		return ;
	}
	int y; //下一个点 
	while(!que.empty()){
		hd=que.front(); que.pop();
		if(hd.time>=len){    //按数字加上加减按钮比直接按加减还多,直接输出只按加减情况的值 
			printf("%d\n",len);
			return ;
		}
		for(i=0;i<2;i++){ 
			y=hd.x+dir[i];
			if(y<=500000&&y>=0&&!map[y]){
				po next;
				next.x=y; next.time=hd.time+1;
				if(yu(next.x)){ 
					next.time+=key;
					if(next.time>=len){
						printf("%d\n",len);
						return ;
					}
					
					printf("%d\n",next.time);
					return ;
				}
				else{   
					map[next.x]=1;
					que.push(next);
				}
			}
		}
	}
	printf("%d\n",len);
	return ;
}
int main(){
	int i,n,s,t,q,len;
	while(~scanf("%d%d%d",&n,&s,&t)){
		memset(a,0,sizeof(a));
		memset(map,0,sizeof(map));
		for(i=0;i<n;i++){  //如2,3键不能用时,a={0,0,1,1,0,0,0,0,0,0} 
			scanf("%d",&q);
			a[q]=1;
		}  
		if(s==t){  //起始点就是目标时 
			printf("0\n");
			continue;
		}
		if(s<t) len=t-s;
		else len=s-t;  //只按加或减要按len下到达 
		po p;
		p.x=t, p.time=0;
		map[p.x]=1;
		bfs(p,len);
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值