2016年 河南工业大学校赛 J 题.爱看电视的LsF

爱看电视的LsF

时间限制: 1 秒  内存限制: 64 MB  |  提交: 437  解决: 125
  

题目描述

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 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
" , result) ; 
    }
    return 0 ; 
}
原文地址:https://www.cnblogs.com/yi-ye-zhi-qiu/p/7881971.html