爱看电视的LsF
时间限制: 1 秒 内存限制: 64 MB | 提交: 437 解决: 125
题目描述
LsF(刘师傅)非常喜欢看电视!
不幸的是,遥控器上的一些数字按钮坏了。 但他灵光一闪,如果他不能直接输入他想要看到的频道的号码,那么他可以先输入其他号码,再通过按下按钮+ 和- (这两个按钮由24K钛合金制成,永远不会坏)的方式到达所需的频道。 按钮+将数字增加1,按钮-将数字减少1。当然他依然可以使用那些完好无损的数字按钮输入号码。
他最初在第S频道,他想看第T频道。他想知道由S到T频道所需的最少按钮按压次数。
输入
输入包含多组数据。
对于每组数据,第一行是三个整数n,S,T(n≤10,0≤S,T≤500,000。 第二行是n个数字 a1,a2,...,an,表示数字 ai键已经坏了 (0≤ai≤9,ai≠aj when i≠j)。
输出
输入包含多组数据。
对于每组数据,第一行是三个整数n,S,T(n≤10,0≤S,T≤500,000。 第二行是n个数字 a1,a2,...,an,表示数字 ai键已经坏了 (0≤ai≤9,ai≠aj when i≠j)。
样例输入
10 1 100 0 1 2 3 4 5 6 7 8 9 9 1 100 0 1 2 3 4 5 6 7 8
样例输出
99 3
题意:
思路:如果想要 按键次数最少 , 则需要用最少的按键次数生成一个 距离目标 更近的 数字 , 之后 通过 按上下键 到达目标 , 则初状态就是 直接通过上下按键到达 目标的按键次数
abs(s-t) ; 注意 目标t 最大为500000 ,则只需生成1000000 以内的 数就可以了 , 通过有限个按键 重复按下 组合成不同的数字 然后松弛最优解 不就是 dfs()吗?
然后 dfs() 一发 过
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std ; #define maxn 550000 int a[10] ; int n , s, t , result ; bool visit[maxn] ; void dfs(int num , int step ){ if(step>=7){//数字超过 1000000 就返回 return; } // abs(num-t) 是经过上下到达目标 // step 按键组合数字的按键次数 if(abs(num-t) + step < result){ result = abs(num-t) + step ; } //向下搜索 for(int i=0 ; i<10 ; i++){ if(!a[i]){ dfs(num*10+i , step+1) ; } } } int main(){ while(~scanf("%d %d %d" , &n , &s , &t)){ int pos ; memset(a , 0 , sizeof(a)) ; for(int i=1 ; i<= n ; i++){ scanf("%d" , &pos) ; a[pos] = 1 ; } //初状态 result = abs(t - s) ; //所有可能的 第一个按键 for(int i=0 ;i<10 ; i++){ if(!a[i]){ dfs(i , 1 ) ; } } printf("%d\n" , result) ; } return 0 ; }