hihocoder 1426 What a Ridiculous Election

本文介绍了一个基于BFS算法解决特定数字转换问题的方法。该问题要求通过一系列操作将初始数字12345转换为另一个五位数,并且需要找到完成转换所需的最少操作次数。文中详细解释了如何使用广度优先搜索进行预处理,记录每一步的状态及剩余操作,最终实现高效求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:What a Ridiculous Election

题目大意:有三种操作:
1、交换相邻两个数
2、对某一个数位上的数,数值加一,对十求余,这个操作最多用3次
3、对某一个数位上的数,数值乘二,对十求余,这个操作最多用2次
现在问你能不能从12345变成给定的数字(五位数),能的话输出最少的操作数

题目思路:BFS预处理一下,res数组记一下数字,剩余的操作2,剩余的操作3,然后模拟的时候好好做一下就好了


#include <map>
#include <set>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;
const int maxn = 1e5+10;
const int inf = 0x3f3f3f3f;

char s[10];
bool flag,vis[10];
int res[maxn][5][5];

struct node{
    int a[10],sec,thr,step;
    bool operator < (const node &a)const{
        return step > a.step;
    }
};

node target;

int check(node now){
    int num = 0;
    for(int i = 1;i <= 5;i++)
        if(now.a[i] != target.a[i]) return 0;
    return 1;
}

int turn(node now){
    int sum = 0;
    for(int i = 1;i <= 5;i++){
        sum += now.a[i];
        sum *= 10;
    }
    sum /= 10;
    return sum;
}

void bfs(node now){
    priority_queue<node>q;
    q.push(now);
    int tmp = turn(now);
    res[tmp][now.sec][now.thr] = 0;

    node u,next;
    bool flag;
    while(!q.empty()){
        u = q.top();
        q.pop();
        for(int i = 2;i <= 5;i++){
            next = u;
            next.step++;
            swap(next.a[i],next.a[i-1]);
            int p = turn(next);
            if(next.step >= res[p][next.sec][next.thr]) continue;
            q.push(next);
            res[p][next.sec][next.thr] = next.step;
        }
        if(u.sec > 0){
            for(int i = 1;i <= 5;i++){
                next = u;
                next.sec--;
                next.step++;
                next.a[i] = (next.a[i]+1)%10;
                int p = turn(next);
                if(next.step >= res[p][next.sec][next.thr]) continue;
                q.push(next);
                res[p][next.sec][next.thr] = next.step;
            }
        }
        if(u.thr > 0){
            for(int i = 1;i <= 5;i++){
                next = u;
                next.thr--;
                next.step++;
                next.a[i] = (next.a[i]*2)%10;
                int p = turn(next);
                if(next.step >= res[p][next.sec][next.thr]) continue;
                q.push(next);
                res[p][next.sec][next.thr] = next.step;
            }
        }
    }
}

int main(){
    node now;
    now.sec = 3,now.thr = 2,now.step = 0;
    for(int i = 1;i <= 5;i++) now.a[i] = i;
    memset(res,inf,sizeof(res));
    bfs(now);
    while(~scanf("%s",s)){
        for(int i = 1;i <= 5;i++) target.a[i] = s[i-1]-'0';
        int p = turn(target);
        int ans = inf;
        for(int i = 0;i <= 3;i++)
            for(int j = 0;j <= 2;j++)
                ans = min(ans,res[p][i][j]);
        if(ans == inf) puts("-1");
        else printf("%d\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值