第1部分 基礎算法(提高篇)--第4章 廣搜的優化技巧1453:移動玩具

1453:移動玩具

時間限制: 1000 ms 內存限制: 65536 KB
提交數: 296 通過數: 172
【題目描述】
原題來自:HAOI 2008

在一個 4×4 的方框內擺放了若干個相同的玩具,某人想將這些玩具重新擺放成爲他心中理想的狀態,規定移動時只能將玩具向上下左右四個方向移動,並且移動的位置不能有玩具,請你用最少的移動次數將初始的玩具狀態移動到目標狀態。

【輸入】
前四行表示玩具的初始狀態,每行 4 個數字 1 或 0,1 表示方格中放置了玩具,0 表示沒有放置玩具。

接着是一個空行。

接下來四行表示玩具的目標狀態,每行 4 個數字 1 或 0,意義同上。

【輸出】
一個整數,所需要的最少移動次數。

【輸入樣例】
1111
0000
1110
0010

1010
0101
1010
0101
【輸出樣例】
4


思路:深搜暴力求解,對於已經匹配好的點,我們直接把他賦值爲0;這個點去匹配其他點,肯定不如直接用這個點已匹配的點更優。如果另一個點的某條轉移路徑需要路過這個點,我們可以轉換爲:把這個點先轉移到目標點,然後再把另一個點轉移過來。 我們只需要求得未匹配點到未匹配目標點的最短距離即可。 這個用數學方式:兩點x座標差的絕對值+兩點y座標的絕對值,即 abs(x1 - x2)+ abs(y1 - y2)。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include<cmath>
#define INF 0x3f3f3f3f
using namespace std;
struct node {
	int x,y;
} c[26] ;//記錄每一個a[][]有玩具的位置 
int a[5][5],b[5][5],w[5][5][5][5] ;
bool d[5][5];
int _sum = 0,_min = INF ;//_sum記錄 a[][] == 1 的個數, _min 是最小值 (答案) 
void BFS ( int tot , int ans ) {//tot 是尋找到的個數 , ans 是需要步數 
	if ( tot > _sum ) {  //當搜索個數 > 原本個數時,跳出 
		_min = min ( _min , ans ) ; // 統計答案 
		return ;
	}
	for ( int i = 1 ; i <= 4 ; i ++ ) {
		for ( int j = 1 ; j <= 4 ; j ++ ) {
			if ( w[c[tot].x][c[tot].y][i][j] != 0 && d[i][j] == 0) {
				d[i][j] = 1 ;
				BFS ( tot + 1 , ans + w[c[tot].x][c[tot].y][i][j] ) ; //進入更深一層的遞歸  
				d[i][j] = 0 ; //回溯 
			}
		}
	}//查找 
}

int main() {
	char ch ;//用字符更好輸入 
	for ( int i = 1 ; i <= 4 ; i ++ ) {
		for ( int j = 1 ; j <= 4 ; j ++ ) {
			cin >> ch;
			a[i][j] = ch - '0' ;
		}
	}//輸入 
	for ( int i = 1 ; i <= 4 ; i ++ ) {
		for ( int j = 1 ; j <= 4 ; j ++ ) {
			cin >> ch ;
			b[i][j] = ch - '0' ;
			if ( a[i][j] == b[i][j] ) a[i][j] = b[i][j] = 0 ;
		}
	}//輸入
	for (int i = 1 ; i <= 4 ; i ++ ) {
		for (int j = 1 ; j <= 4 ; j ++ ) {
			if (a[i][j] == 1) {
				c[++ _sum].x = i;
				c[_sum].y = j ;
				for (int k = 1; k <= 4; k ++) {
					for (int x = 1 ; x <= 4; x ++) {
						if (b[k][x] == 1) w[i][j][k][x] = abs(i - k) + abs(j - x) ;
					}
				}
			}
		}
	}//w[][][][]儲存(i,j) -->  (k,x) 的距離 
	BFS(1,0);//BFS搜索 
	printf("%d",_min);//輸出 
	return 0 ;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章