1. 程式人生 > >【vjudge】八數碼問題

【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特性。