哆啦A梦的时光机
哆啦A梦有一个神奇的道具:时光机。坐着它,大雄和他的伙伴们能穿越时空,回到过去或者去到未来。
有一天,大雄和他的伙伴们想穿越时空进行探险,可是时光机却出了一点故障,只能进行有限的时空穿越操作。大雄他们需要从现在出发,到达一个目标时间点进行探险,结束后再返回到现在,他们希望尽可能减少时光机的操作次数,你能帮助他们吗?
假设大雄和他的伙伴们出发的时间点(现在)为S(0<S<1,000,000),希望到达的时间点(目标)为 T(0<T<1,000,000),已知时光机可以进行如下的时空穿越操作(X 为正整数):
可以从任意时刻X穿越到 X+1 或者 X−1 时刻
可以从任意时刻X穿越到X×2 时刻
当 X 为偶数时,可以从 X 时刻穿越到 X/2 时刻
请问,大雄和他的伙伴们从 S 时刻出发,先到达 T 时刻,再回到 S 时刻最少需要多少次时空穿越操作?
输入格式
输入的第一个数是一个正整数 N,表示测试数据一共有 N 组(0<N<20)。之后有 N 行,每一行包含两个正整数 S 和 T,表示出发和到达时间点。S not = T
输出格式
输出包括N行,每一行一个正整数,表示每组测试数据对应的最少时光机操作次数。
样例解释
对于 S=5,T=17:
操作如下:5->4->8->16->17->16->8->4->5
对于 S=4,T=8:操作如下:4->8->4
样例输入复制
2 5 17 4 8
样例输出复制
8 2
#include <cstdio>
#include <queue>
#include <iostream>
#include <cstring>
using namespace std;
queue<pair<int,int> > q;
bool vis[1000001];
int main(){
int n,s,t,now,step;
cin >> n;
while(n--){
cin >> s >> t;
while(!q.empty()){
q.pop();
}
memset(vis,0,sizeof(vis));
q.push(make_pair(s,0));
vis[s] = true;
while(!q.empty()){
now = q.front().first;
step = q.front().second;
q.pop();
if(now == t){
cout << 2 * step << endl;
break;
}
if(now - 1 > 0 && !vis[now -1]){
vis[now - 1] = true;
q.push(make_pair(now - 1,step + 1));
}
if(now + 1 < 1000000 && !vis[now + 1]){
vis[now + 1] = true;
q.push(make_pair(now + 1,step + 1));
}
if(now * 2 < 1000000 && !vis[now * 2]){
vis[now * 2] = true;
q.push(make_pair(now * 2,step + 1));
}
if(now % 2 == 0 && !vis[now / 2]){
vis[now / 2] = true;
q.push(make_pair(now / 2,step + 1));
}
}
}
return 0;
}
密码锁
现在一个紧急的任务是打开一个密码锁。密码由四位数字组成,每个数字从 1 到 9 进行编号。每次可以对任何一位数字加 1 或减 1。当将9
加 1 时,数字将变为1
,当1
减 1 的时,数字将变为9
。你也可以交换相邻数字,每一个行动记做一步。现在你的任务是使用最小的步骤来打开锁。注意:最左边的数字不与最右边的数字相邻。
输入格式
第一行输入四位数字,表示密码锁的初始状态。
第二行输入四位数字,表示开锁的密码。
输出格式
输出一个整数,表示最小步骤。
样例输入复制
1234 2144
样例输出复制
2
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
using namespace std;
struct node{
int num[4],step;
}first,last;
int vis[11][11][11][11];
void bfs(){
int i ;
node a,next;
queue<node> q;
a = first;
a.step = 0;
q.push(a);
memset(vis,0,sizeof(vis));
vis[a.num[0]][a.num[1]][a.num[2]][a.num[3]] = 1;
while(!q.empty()){
a = q.front();
q.pop();
if(a.num[0] == last.num[0] &&a.num[1] == last.num[1] &&a.num[2] == last.num[2] &&a.num[3] == last.num[3]){
cout << a.step;
return ;
}
for(i = 0;i < 4;i++){
next = a;
next.num[i]++;
if(next.num[i] == 10){
next.num[i] = 1;
}
if(!vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]]){
vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]] = 1;
next.step ++;
q.push(next);
}
}
for(i = 0;i < 4;i++){
next = a;
next.num[i]--;
if(next.num[i] == 0){
next.num[i] = 9;
}
if(!vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]]){
vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]] = 1;
next.step ++;
q.push(next);
}
}
for(i = 0;i < 3;i++){
next = a;
next.num[i] = a.num[i + 1];
next.num[i + 1] = a.num[i];
if(!vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]]){
vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]] = 1;
next.step ++;
q.push(next);
}
}
}
}
int main(){
int i,j,t;
char s1[10],s2[10];
scanf("%s%s",s1,s2);
for(int i = 0;i < 4;i++){
first.num[i] = s1[i] - '0';
last.num[i] = s2[i] - '0';
}
bfs();
return 0;
}
迷宫
给定一个 m×n 的迷宫,迷宫中有两个位置,蒜头君想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,蒜头君可以穿越,有些地方是障碍,他必须绕行,从迷宫的一个位置,只能走到与它相邻的 4 个位置中,当然在行走过程中,蒜头君不能走到迷宫外面去。令人头痛的是,蒜头君是个没什么方向感的人,因此,他在行走过程中,不能转太多弯了,否则他会晕倒的。我们假定给定的两个位置都是空地,初始时,蒜头君所面向的方向未定,他可以选择 4 个方向的任何一个出发,而不算成一次转弯。蒜头君能从一个位置走到另外一个位置吗?
输入格式
第 1行为一个整数 t (1≤t≤100),表示测试数据的个数,接下来为 t 组测试数据。
每组测试数据第 1 行为两个整数 m,n(1≤m,n≤100),分别表示迷宫的行数和列数,接下来 m 行,每行包括 n 个字符,其中字符'.'
表示该位置为空地,字符'*'
表示该位置为障碍,输入数据中只有这两种字符,每组测试数据的最后一行为 5 个整数k,x1,y1,x2,y2 (1≤k≤10,1≤x1,x2≤n,m1≤y1,y2≤m),其中 kk 表示蒜头君最多能转的弯数,(x1,y1),(x2,y2) 表示两个位置,其中x1,x2 对应列,y1,y2 对应行。
输出格式
每组测试数据对应为一行,若蒜头君能从一个位置走到另外一个位置,输出"yes"
,否则输出"no"
。
样例输入复制
2 5 5 ...** *.**. ..... ..... *.... 1 1 1 1 3 5 5 ...** *.**. ..... ..... *.... 2 1 1 1 3
样例输出复制
no yes
#include <cstdio>
#include <iostream>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e2 + 9;
char mp[N][N];
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
int n,m,k,a,b,x,y;
int vis[N][N];
struct node{
int x,y,k,dir;
node(){}
node(int _x,int _y,int _k,int _dir){
x = _x;
y = _y;
k = _k;
dir = _dir;
}
};
void bfs(){
queue<node> q;
q.push(node(a,b,-1,-1));
memset(vis,0x3f,sizeof(vis));
vis[a][b] = -1;
while(!q.empty()){
node g = q.front();
q.pop();
if(g.x == x && g.y == y){
cout << "yes";
return ;
}
for(int i = 0;i <4;i++){
int tx = g.x + dx[i];
int ty = g.y + dy[i];
int kk = g.k + (g.dir != i);
if(tx >= 0 && tx < n && ty >= 0 && ty < m && mp[tx][ty] == '.' && kk <= k && vis[tx][ty] > kk){
vis[tx][ty] = kk;
q.push(node(tx,ty,kk,i));
}
}
}
cout << "no";
}
int main(){
int t;
cin >> t;
while(t--){
cin >> n >> m;
for(int i = 0;i < n;i++){
cin >> mp[i];
}
cin >> k >> b >> a >> y >> x;
a--,b--,x--,y--;
bfs();
cout << endl;
}
return 0;
}