hiho 1426

题目大意:

问最少通过多少次操作能将字符串"12345"变成一个长度为5并且只由'0'~'9'字符组成的字符串

每次操作有3种选择

1.交换相邻的两个数字

2.将一个数字加1,如果大于9就模10

3.将一个数字乘2,如果大于9就模10

2操作最多能用3次,3操作最多能用2次。

思路:题目中可能有100000组测试数据,所以可以用bfs来预处理,得出“12345”通过以上操作能转换成的字符串的最少操作次数。

易错点:因为第2步操作仅能使用3次,第3步操作仅能操作2次,所以必须开一个res[5][5][100005]的数组,res[i][j][k]表示意思第2步操作还可以进行i次,第3步操作还可以进行j次所得到数字为k的最少操作次数,将此状态入队列。刚开始仅仅开了一个res[i]表示状态,导致有些情况没有考虑,如前面已经进行了2次第3步操作得到一个数字k,这时候已经无法进行第3步操作,但是其实可能有其他操作可以使用比如1次第3步操作得到这个数字k,那么此时还可以继续进行第3步操作,有可能使操作步数减少。如果只开一维res数组则无法考虑这种情况。


代码如下:

#include<iostream>
using namespace std;
#include<stdio.h>
#include<string.h>
#include<string>
#include<queue>
#include<algorithm>
const int inf = 200000;
int res[5][5][100005];
int result[100005];
int min(int x,int y)
{
if(x<y) return x;
return y;
}
struct num
{
int sec;
int third;
int val;
int pace;
};
void turn(int x,int a[])
{
int i;
for(i=4;i>=0;i--)
{
a[i] = x % 10;
x /= 10;
}
}
int change(int b[])
{
int i;
int x = 0;
for(i=0;i<5;i++) x = x * 10 + b[i];
return x;

queue<num> que;
void bfs(int now)
{
num tm;
tm.val = now;
tm.sec = 3;
tm.third = 2;
tm.pace = 0;
que.push(tm);
int i,j;
while(!que.empty())
{
tm = que.front();
que.pop();
int a[5];
turn(tm.val,a);
for(i=1;i<5;i++)
{
swap(a[i-1],a[i]);
int x = change(a);
if(res[tm.sec][tm.third][x]==inf)
{
num tt;
tt.pace = tm.pace + 1;
tt.sec = tm.sec;
tt.third = tm.third;
tt.val = x;
res[tm.sec][tm.third][x] = tt.pace;
result[x] = min(result[x],tt.pace);
que.push(tt);
}
swap(a[i-1],a[i]);
}
int b[5];
if(tm.sec>0)
{
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
b[j] = a[j];
}
b[i] = (a[i] + 1) % 10;
int x = change(b);
if(res[tm.sec-1][tm.third][x]==inf)
{
num tt;
tt.pace = tm.pace + 1;
tt.sec = tm.sec - 1;
tt.third = tm.third;
tt.val = x;
res[tm.sec-1][tm.third][x] = tt.pace;
result[x] = min(result[x],tt.pace);
que.push(tt);
}
}
}
if(tm.third>0)
{
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
b[j] = a[j];
}
b[i] = (a[i] * 2) % 10;
int x = change(b);
if(res[tm.sec][tm.third-1][x]==inf)
{
num tt;
tt.pace = tm.pace + 1;
tt.sec = tm.sec;
tt.third = tm.third - 1;
tt.val = x;
res[tm.sec][tm.third-1][x] = tt.pace;
result[x] = min(result[x],tt.pace);
que.push(tt);
}
}
}
}
}
int main()
{
int now = 12345;
int m,i,j,k;
for(i=0;i<=3;i++)
for(j=0;j<=2;j++)
for(k=0;k<100000;k++) res[i][j][k] = inf;
fill(result,result+100003,inf);
res[3][2][now] = 0;
result[now] = 0;
bfs(now);
while(~scanf("%d",&m))
{
if(result[m]==inf) printf("-1\n");
else printf("%d\n",result[m]);
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
项目:使用AngularJs编写的简单 益智游戏(附源代码)  这是一个简单的 javascript 项目。这是一个拼图游戏,也包含一个填字游戏。这个游戏玩起来很棒。有两个不同的版本可以玩这个游戏。你也可以玩填字游戏。 关于游戏 这款游戏的玩法很简单。如上所述,它包含拼图和填字游戏。您可以通过移动图像来玩滑动拼图。您还可以选择要在滑动面板中拥有的列数和网格数。 另一个是填字游戏。在这里你只需要找到浏览器左侧提到的那些单词。 要运行此游戏,您需要在系统上安装浏览器。下载并在代码编辑器中打开此项目。然后有一个 index.html 文件可供您修改。在命令提示符中运行该文件,或者您可以直接运行索引文件。使用 Google Chrome 或 FireFox 可获得更好的用户体验。此外,这是一款多人游戏,双方玩家都是人类。 这个游戏包含很多 JavaScript 验证。这个游戏很有趣,如果你能用一点 CSS 修改它,那就更好了。 总的来说,这个项目使用了很多 javascript 和 javascript 库。如果你可以添加一些具有不同颜色选项的级别,那么你一定可以利用其库来提高你的 javascript 技能。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值