CodeChef Digit Jumps解题报告

Digit Jumps

题面

中文题面在这里:https://s3.amazonaws.com/codechef_shared/download/translated/JUNE14/mandarin/DIGJUMP.pdf
Chef loves games! But he likes to invent his own. Now he plays game "Digit Jump". Chef has sequence of digits S1, S2,..., SN,. He is staying in the first digit (S1) and want to reach the last digit (SN) in the minimal number of jumps.

While staying in some digit x with index i (digit Si) Chef can jump into digits with indices i - 1 (Si-1) and i + 1 (Si+1) but he can't jump out from sequence. Or he can jump into any digit with the same value x.

Help Chef to find the minimal number of jumps he need to reach digit SN from digit S1.

Input
Input contains a single line consist of string S of length N- the sequence of digits.

Output
In a single line print single integer - the minimal number of jumps he needs.

Constraints
1 ≤ N ≤ 10^5
Each symbol of S is a digit from 0 to 9.

Example
Input:
01234567890

Output:
1

Input:
012134444444443

Output:
4

Explanation

In the first case Chef can directly jump from the first digit (it is 0) to the last (as it is also 0).

In the second case Chef should jump in such sequence (the number of digits from 1: 1-2-4-5-15).

题解

我看好多好多人都说这个题好简单的好像直接bfs就跳完了
是不是我也可以这么说??

代码(蒯的)

#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;
#define Maxn 100000
char s[Maxn+5];
int n;
int a[Maxn+5];
queue<int> q;
vector<int> x[10];
bool in[Maxn+5];
bool vis[10];
void bfs(){
    q.push(1);
    a[1]=0;
    in[1]=1;
    int now;
    while(!q.empty()){
        now=q.front();
        if(now==n){
            break;
        }
        in[now]=0;
        q.pop();
        if(now-1>0&&a[now-1]>a[now]+1){
            a[now-1]=a[now]+1;
            if(!in[now-1]){
                q.push(now-1);
                in[now-1]=1;
            }
        }
        if(now+1<=n&&a[now+1]>a[now]+1){
            a[now+1]=a[now]+1;
            if(!in[now+1]){
                q.push(now+1);
                in[now+1]=1;
            }
        }
        if(vis[s[now]-'0']){
            continue;
        }//每一个数只要跳一次即可,后面来的肯定不会更优
        vis[s[now]-'0']=1;
        for(int i=0;i<(int)x[s[now]-'0'].size();i++){
            if(a[x[s[now]-'0'][i]]>a[now]+1){
                a[x[s[now]-'0'][i]]=a[now]+1;
                if(!in[x[s[now]-'0'][i]]){
                    q.push(x[s[now]-'0'][i]);
                    in[x[s[now]-'0'][i]]=1;
                }
            }
        }
    }
}
int main(){
    memset(a,0x3f,sizeof a);
    scanf("%s",s+1);
    while(s[++n]!='\0'){
        x[s[n]-'0'].push_back(n);
    }
    n--;
    bfs();
    printf("%d\n",a[n]);
    return 0;
}

转载于:https://www.cnblogs.com/cancers/p/11282369.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值