【vjudge】八數碼問題
Eight
The 15-puzzle has been around for over 100 years; even if you don’t know it by that name, you’ve seen it. It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile missing. Let’s call the missing tile ‘x’; the object of the puzzle is to arrange the tiles so that they are ordered as:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 x
where the only legal operation is to exchange ‘x’ with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves a slightly scrambled puzzle:
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8
9 x 10 12 9 10 x 12 9 10 11 12 9 10 11 12
13 14 11 15 13 14 11 15 13 14 x 15 13 14 15 x
r-> d-> r->
The letters in the previous row indicate which neighbor of the ‘x’ tile is swapped with the ‘x’ tile at each step; legal values are ‘r’,’l’,’u’ and ‘d’, for right, left, up, and down, respectively.
Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and
frustrating many people. In fact, all you have to do to make a regular puzzle into an unsolvable one is to swap two tiles (not counting the missing ‘x’ tile, of course).
In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three
arrangement.
Input
You will receive a description of a configuration of the 8 puzzle. The description is just a list of the tiles in their initial positions, with the rows listed from top to bottom, and the tiles listed from left to right within a row, where the tiles are represented by numbers 1 to 8, plus ‘x’. For example, this puzzle
1 2 3
x 4 6
7 5 8
is described by this list:
1 2 3 x 4 6 7 5 8
Output
You will print to standard output either the word “unsolvable”, if the puzzle has no solution, or a string consisting entirely of the letters ‘r’, ‘l’, ‘u’ and ‘d’ that describes a series of moves that produce a solution. The string should include no spaces and start at the beginning of the line.
Sample Input
2 3 4 1 5 x 7 6 8
Sample Output
ullddrurdllurdruldr
【題目解析】
這道題目是一道典型的搜尋題目,什麼搜尋?自然是廣搜。面對這一道題,其中最為複雜的就是如何儲存?如何判重?你想到了嗎?
面對如何儲存的這一個問題,我選擇了棧,因為它可以更好的幫助我儲存。至於如何判重,我選擇了先用一個一維陣列儲存,再運用以下方法:
若有5個數; 2 4 5 7 8
我們如何來進行判重呢?
首先我們需要一個 bool 陣列來標記曾經產生過的值,避免重複產生。
那我們如何產生這樣一個值呢?
這時,需要兩個 for 迴圈來輔助,不光如此,我們還需要一個階層的陣列,以輔助產生。
第一個 for 列舉第一個數 i:1~n(從前往後),第二數列舉 j:i+1~n (從前往後),一旦遇到比第一個數小的就加上 [8-j]的階層如此,我們就創造出了一個數所獨有的自己的編碼。至於為什麼是 8-j 而不是 j,也是為了運算速度著想,不過,也可以用 j。
知道了這個方法,媽媽再也不用擔心我的判重了(-__-),另外一個需要注意的是:如何判斷是否越界?請細細理解下面這段程式碼:
if(push.where<0||push.where>8||(i%2&&push.where/3!=first.where/3))
push.where and first.where為新的位置編號與原來的位置編號。這裡的判重終點是左右走(判斷的行號)。
好啦,下面自己消化程式碼吧 -_-
【程式碼】
狀態:AC
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
int Jc[15]={1,1,2,6,24,120,720,5040,40320,362880,3628800};
int Fx[4]={-3,-1,3,1};
char Sc[4]={'u','l','d','r'};
struct Queue
{
int num[15];
int Dad,F,where;
}a[600000];
Queue begin;
bool map[362885];
bool Dd(int n[])
{
for(int i=0;i<8;i++)
if(n[i]!=i+1)
return false;
return true;
}
bool Pc(int n[])
{
int lj=0;
for(int i=0;i<9;i++)
for(int j=i+1;j<9;j++)
if(n[j]<n[i])
lj+=Jc[8-i];
if(map[lj]) return true;
map[lj]=true;
return false;
}
int main()
{
int l=0,r=0;
char c=0;
begin.Dad=begin.F=-1;
for(int i=0;i<9;i++)
{
scanf("%c",&c);
if(c-'0'==-16)scanf("%c",&c);
if(c!='x')begin.num[i]=c-'0';
else begin.num[i]=0,begin.where=i;
}
//for(int i=0;i<9;i++)
//printf("%d ",begin.num[i]);
a[r++]=begin;
while(l<r)
{
Queue first;
first=a[l];
for(int i=0;i<4;i++)
{
Queue push=first;
push.Dad=l,push.F=i,push.where=Fx[i]+first.where;
if(push.where<0||push.where>8||(i%2&&push.where/3!=first.where/3)) continue;
swap(push.num[push.where],push.num[first.where]);
if(Pc(push.num)) continue;
a[r++]=push;
if(Dd(push.num))
{
int x=r-1;
vector<int> vec;
while(true)
{
vec.push_back(a[x].F);
x=a[x].Dad;
if(x==-1) break;
}
for(int j=vec.size()-2;j>=0;j--)
printf("%c",Sc[vec[j]]);
printf("\n");
return 0;
}
}
l++;
}
printf("NO SOLUTION\n");
return 0;
}
相關推薦
【vjudge】八數碼問題
Eight The 15-puzzle has been around for over 100 years; even if you don’t know it by that name, you’ve seen it. It is constructed
【9018:1368】八數碼
mit tdi 只有一個 數碼 namespace gre pid 輸入 define 1368: 八數碼 時間限制: 1 Sec 內存限制: 1024 MB提交: 81 解決: 32[提交][狀態][討論版] 題目描述 在3×3的棋盤上,擺有八個棋子,每個棋子上標
【NOJ1571】【演算法實驗三】【分支限界法】八數碼
1571.八數碼 時限:5000ms 記憶體限制:20000K 總時限:10000ms 描述 在九宮格里放在1到8共8個數字還有一個是空格,與空格相鄰的數字可以移動到空格的位置,問給定的狀態最少需要幾步能到達目標狀態(用0表示空格): 1 2 3 4 5 6 7 8
【C++演算法設計】八數碼問題
八數碼問題 【題意】 編好為1~8的8個正方形滑塊擺成3行3列(一個格子為空),如圖所示 每次可以移動空格相鄰的滑塊到空格,要計算出能移動出目標局面的最小步數,如無法達到則輸出-1。 【分析】 我們可以把每一種局面定義為一種“狀態”,而每個狀態就是由9個格子的編號依次排
【轉載】八、商品詳情頁功能
nero tle 文件 tro 過濾器 price 搜索 應該 == 八、商品詳情頁功能 8.1.viewsets實現商品詳情頁接口 (1)商品詳情頁只需要多繼承一個類(mixins.RetrieveModelMixin)就可以了 class GoodsListV
【轉載】八年phper的高階工程師面試之路
這是一篇反面教材,希望也能引起部分程式設計師的警惕。 最近半個月時間,經過幾次面試,差不多已經對自己有了定位————距離騰訊T3崗位還是有一點距離。 因為在一家小公司呆的習慣了(6年),公司沒有人在技術層面超過我,作為技術核心,感覺自己
【人工智慧】八皇后問題-啟發式求解
摘要 八皇后問題是回溯演算法的典型案例,在回溯法中,常常是盲目搜尋,耗費過多的搜尋時間。在本次實驗中,使用了啟發式搜尋,搜尋時不是任取一個分支,而是選擇最佳的分支往下搜尋。通過定義狀態空間、操作規
【English】八、食物相關
nbsp 意大利面 raw fish off ice ast 啤酒 urg 一、beer、wine、coffee、soup、oil、juice beer 啤酒 They drink beer. wine 葡萄酒 Wine and coffee.
【基礎練習】【BFS+A*】codevs1225八數碼難題題解
一點 說明 優先 data- push 練習 bool csdn tarjan 題目描寫敘述 Description Yours和zero在研究A*啟示式算法.拿到一道經典的A*問題,可是他們不會做,請你幫他們. 問題描寫敘述 在3×3的棋
【轉】A*算法解決八數碼問題
nim fir 空格 sin get () explore sed deepcopy from utils import ( PriorityQueue) import copy infinity = float(‘inf‘) def best_first_gr
【 HDU1043-經典BFS+康拓展開 八數碼】 (待更)
給定一個序列,由1~8數字和字母x組成,表示的是一個3*3的矩形。每次操作x都能與相鄰的數字交換,問如何操作才能使得序列為{1,2,3,4,5,6,7,8,x}。 //多組資料-需要計算全部路徑後直接輸出 //反向搜尋+打表(離線) #include<iostream&
HDU3567 進階搜尋 IDA*演算法 八數碼【經典】
題意是給你兩個八數碼,讓你輸出從第一個八數碼到第二個八數碼的最短路徑,且要求該路徑也是最短路徑下的字典序最小的路徑。 思路:我一開始以為只是簡單的在結構體判定一下,讓其按照字典序最小的順序去尋路,後來發現這樣做的後果是路徑不是最小,嗯。於是就上網查部落格,然後就學會了A*演算法的升級版IDA
【轉】【修真院“善良”系列之十八】WEB程序員從零開始到就業的全資料V1.0——只看這一篇就夠了!
absolute feed 自己 session rem 好的 ans 一個 css樣式 這是兩年以來,修真院收集整理的學習資料順序。以CSS15個任務,JS15個任務為基礎,分別依據要完成任務的不同的技能點,我們整理出來了這麽一篇在學習的時候需要看到的資料。這是Versi
【轉】JMeter學習(十八)JMeter測試Java(二)
sets interval permsize int 文件 不同 時間 結果 argument 實例: 服務為:將輸入的兩個參數通過IO存入文件; 1、打開MyEclipse,編寫Java代碼 服務: package test; import java.io.F
【轉】JMeter學習(二十八)內存溢出解決方法
不能 -xms 百度 解決 code apache 超過 軟件測試 內存 使用jmeter進行壓力測試時遇到一段時間後報內存溢出outfmenmory錯誤,導致jmeter卡死了,先嘗試在jmeter.bat中增加了JVM_ARGS="-Xmx2048m -Xms2048m
【Python】七段數碼顯示管
間隔 main str 函數 pla hid ria 數碼管 awd #DrawSevenSegDisplay.py import turtle, datetime def drawLine(draw): #繪制單段數碼管 turtle.pendo
【基礎知識八】集成學習
大致 p s 學習方法 ron 完成 ima 結合 alt http 難點:如何產生“好而不同”的個體學習器;“好而不同”:“準確性”和“多樣性” 一、個體與集成 構建並結合多個學習器來完成學習任務 集成:結果通過投票法voting產生,“少數服從多數” 獲得整體性能提升要
【Selenium 3+Java自動化(4)】-八種元素定位
pub nbsp 百度搜索 name tail webdriver nqa pan sss 1 package com.mypro.jase; 2 3 import org.openqa.selenium.By; 4 import org.openqa.sele
計算機網絡【八】:應用層 【轉】
tac 都是 文件共享 編寫 .net pos 遠程 等待 src 轉自:http://blog.chinaunix.net/uid-26275986-id-4110819.html 今天我們來快速地瀏覽一下傳輸層之上的應用層所使用的協議,下面將簡要地列出應用
【SQL】- 基礎知識梳理(八) - 事務與鎖
隔離性 rep del 數據表 訪問 關系 snapshot 轉換 pro 事務的概念 事務:若幹條T-SQL指令組成的一個操作數據庫的最小執行單元,這個整體要麽全部成功,要麽全部失敗。(並發控制) 事務的四個屬性:原子性、一致性、隔離性、持久性。稱為事務的ACID特性。