#include<stdio.h>
#define MAX_N 100000
#define MAX_INT 0x7fffffff //32位
int frontQueue[MAX_N+2], rearQueue[MAX_N+2]; // 前後隊列
int location[MAX_N+2];
void init(){
int i;
for(i = 0; i <= MAX_N; i++) {
frontQueue[i] = -2;
rearQueue[i] = -2;
location[i] = MAX_INT;
}
}
int getNextFromFront(int loc , int which) {
if(which == 0) {
return loc-1;
}else if(which == 1) {
return loc+1;
}else if(which == 2) {
return loc*2;
}
return -1;
}
int getNextFromRear(int loc, int which) {
if(which == 0) {
return loc-1;
}else if(which == 1) {
return loc+1;
}else if(which == 2 && ( loc%2 == 0)) { //注意是能被2整除,和乘以二相反
return loc /2;
}
return -1;
}
int getMinTime(int start , int target){
int step = 0;
int nextLoc, end, j;
int fromIndex1 = 0 , fromIndex2 = 0, toIndex1 = 0, toIndex2 = 0;
int currIndex;
if(start >= target)
return start - target;
location[start] = 0;
location[target] = -1;
frontQueue[toIndex1] = start; // 起點
rearQueue[toIndex2] = target; // 終點
// 前向找到時,直接輸出; 否則前向和後向相交時,返回結果爲相交點上,前後走過步數之和
while(fromIndex1 <= toIndex1 && fromIndex2 <=toIndex2) {
step++; // 記錄步數
end = toIndex1; //結束點
for(currIndex = fromIndex1; currIndex <= end; currIndex++) {
for(j = 0; j < 3; j ++) {
nextLoc = getNextFromFront(frontQueue[currIndex], j);
if(nextLoc == target) return step; //直接找到
if(nextLoc > MAX_N || nextLoc <0) continue;
if(location[nextLoc] == MAX_INT) {
location[nextLoc] = step;
frontQueue[++toIndex1] = nextLoc; // 放入隊列
}else if(location[nextLoc] < 0) { // 和後向隊列相交
return step - location[nextLoc];
}
}
}
fromIndex1 = end + 1; // 更新下一次開始點爲上一次結束點的下一個
end = toIndex2;
for(currIndex = fromIndex2; currIndex <= end; currIndex++) {
for(j = 0; j < 3; j ++) {
nextLoc = getNextFromRear(rearQueue[currIndex], j);
if(nextLoc > MAX_N || nextLoc <0) continue;
if(location[nextLoc] == MAX_INT) {
location[nextLoc] = -step; // 注意是-step
rearQueue[++toIndex2] = nextLoc;
}else if(location[nextLoc] >= 0) {
return step + location[nextLoc];// 和前向隊列相交
}
}
}
fromIndex2 = end + 1;
}
return -1;
}
int main(){
int start , target;
freopen("input.txt", "r", stdin);
scanf("%d %d", &start, &target);
init();
printf("%d\n", getMinTime(start, target));
return 0;
}
2018 03 08更新
學習下雙向BFS, 直接上代碼。。