zoukankan      html  css  js  c++  java
  • 试题 历届试题 九宫重排

    资源限制
    时间限制:1.0s   内存限制:256.0MB
     
    问题描述
      如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。

      我们把第一个图的局面记为:12345678.
      把第二个图的局面记为:123.46758
      显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
      本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
     
    输入格式
      输入第一行包含九宫的初态,第二行包含九宫的终态。
     
    输出格式
      输出最少的步数,如果不存在方案,则输出-1。
     
    样例输入
    12345678.
    123.46758
     
    样例输出
    3
     
    样例输入
    13524678.
    46758123.
     
    样例输出
    22
     
     
    这题与状态和步数相关,首先就是想到搜索,要得到从初态到终态所需最少步数→广搜,一旦出现终态那就是最少步数.
    第一遍写的时候没有记录出现过的局面进行剪枝,于是超时了,后来用map记录出现过的局面,每个局面都用一个字符串表示,重复出现的局面就不再入队了,这样修改之后再提交就能过了.
    不过这种方法并不是很好,耗时长,占内存大(375ms | 21.98MB),搜了一些别人的代码提交了一下,都比这种方法更优(15ms | 13.77MB,125ms | 10.83MB),不过对我来说这种方法比较好理解,也容易想到,总之思路没歪就好.
     
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <string>
     6 #include <cmath>
     7 #include <map>
     8 #include <queue>
     9 #include <algorithm>
    10 #define INF 0x3f3f3f3f
    11 #define zero 1e-7
    12 
    13 using namespace std;
    14 typedef long long ll;
    15 const ll mod=1e9+7;
    16 const ll max_n=5e5+7;
    17 //9*8*7*6*5*4*3*2*1=362880
    18 struct node {
    19     string s;//当前局面
    20     int p;//该局面空格所在位置
    21     int step;//到达当前局面经过了多少步
    22 };
    23 queue<node> q;
    24 map<string, int> mp;//记录出现过的局面
    25 
    26 string s1, s2;//初态,终态
    27 
    28 void add(node t, int p) {//当前局面,新局面中空格所在位置
    29     string ss=t.s;
    30     ss[t.p]=ss[p];
    31     ss[p]='.';
    32     if(mp.find(ss)==mp.end()) {//若局面ss未曾出现过
    33         mp[ss]=1;//记录该局面
    34         node temp={ss, p, t.step+1};
    35         q.push(temp);//将该局面相关信息入队
    36     }
    37 }
    38 //广搜
    39 int bfs() {
    40     while(!q.empty()) {
    41         node t=q.front();
    42         q.pop();
    43         if(t.s==s2) {//一旦该局面与目标局面一致,其步数即最少所需步数
    44             return t.step;
    45         }
    46         int pp;
    47         string ss;
    48         if(t.p/3>0) //空格不在第一行,可与它上方那格数字交换
    49             add(t, t.p-3);
    50         if(t.p/3<2) //空格不在第三行,可与它下方那格数字交换
    51             add(t, t.p+3);
    52         if(t.p%3>0) //空格不在第一列,可与它左边那格数字交换
    53             add(t, t.p-1);
    54         if(t.p%3<2) //空格不在第三列,可与它右边那格数字交换
    55             add(t, t.p+1);
    56     }
    57     return -1;//若无法达到目标局面,则返回-1
    58 }
    59 
    60 int main() {
    61     int p;
    62     mp.clear();
    63     while(!q.empty()) q.pop();//队列清空
    64     cin>>s1>>s2;
    65     for(int i=0; i<9; i++) {
    66         if(s1[i]=='.') {
    67             p=i;
    68             break;
    69         }
    70     }
    71     node temp={s1, p, 0};//当前局面,空格的位置,步数
    72     q.push(temp);
    73     mp[temp.s]=1;
    74     int mint=bfs();
    75     cout<<mint<<endl;
    76     return 0;
    77 }
     
  • 相关阅读:
    Atitit.异步编程技术原理与实践attilax总结
    AjaxToolKit之Rating控件的使用(http://www.soaspx.com/dotnet/ajax/ajaxtech/ajaxtech_20091021_1219.html)
    JavaScript初学指南
    javascript泛型集合类(转)
    HTTP 错误 404.2 Not Found 由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面
    IIS连接oralce数据库时 提示“System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本”
    配置错误定义了重复的“system.web.extensions/scripting/scriptResourceHandler” 解决办法
    self.location.href的具体用法(转)
    CSS Overflow属性详解(转)
    .net中使用showModalDialog打开模式窗口,在后台代码中使用Response.Write()会弹出新页面
  • 原文地址:https://www.cnblogs.com/wwqzbl/p/13586307.html
Copyright © 2011-2022 走看看