zoukankan      html  css  js  c++  java
  • bzoj1085 [SCOI2005]骑士精神

    Description

    在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位。在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空位上。 给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘: 为了体现出骑士精神,他们必须以最少的步数完成任务。

    Input

    第一行有一个正整数T(T<=10),表示一共有N组数据。接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,*表示空位。两组数据之间没有空行。

    Output

    对于每组数据都输出一行。如果能在15步以内(包括15步)到达目标状态,则输出步数,否则输出-1。

    Sample Input

    2
    10110
    01*11
    10111
    01001
    00000
    01011
    110*1
    01110
    01010
    00100

    Sample Output

    7
    -1

    正解:迭代加深搜索+启发式搜索(A*搜索)。

    其实我觉得这题的剪枝就是普通的可行性剪枝而已。。

    直接爆搜肯定T飞,我们考虑如何剪枝。首先,这题用广搜会爆,所以我们用迭代加深搜索。如果当前步数+还需走的步数>要求步数,就可以剪枝了。后面那个可以通过比较当前棋盘与目标棋盘有多少个棋子来确定。然后我们就能成功AC此题。。

     1 //It is made by wfj_2048~
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <cstdio>
     7 #include <vector>
     8 #include <cmath>
     9 #include <queue>
    10 #include <stack>
    11 #include <map>
    12 #include <set>
    13 #define inf (1<<30)
    14 #define il inline
    15 #define RG register
    16 #define ll long long
    17 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    18 
    19 using namespace std;
    20 
    21 const int d1[9]={0,1,2,1,2,-2,-1,-2,-1},d2[9]={0,2,1,-2,-1,1,2,-1,-2};
    22 int a[7][7],goal[7][7],stx,sty,d,flag;
    23 char x;
    24 
    25 il int gi(){
    26     RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    27     if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x;
    28 }
    29 
    30 il char gc(){ RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='*') ch=getchar(); return ch; }
    31 
    32 il int check(int a[7][7]){
    33     for (RG int i=1;i<=5;++i)
    34     for (RG int j=1;j<=5;++j)
    35         if (a[i][j]!=goal[i][j]) return 0;
    36     return 1;
    37 }
    38 
    39 il int go(int a[7][7],RG int had){
    40     RG int res=0;
    41     for (RG int i=1;i<=5;++i)
    42     for (RG int j=1;j<=5;++j)
    43         if (a[i][j]!=goal[i][j]) res++;
    44     return had+res<=d;
    45 }
    46 
    47 il void dfs(int a[7][7],RG int x,RG int y,RG int dep,RG int last){
    48     if (check(a)){ flag=1; return; }
    49     if (dep==d) return; RG int s[7][7],x1,y1;
    50     for (RG int i=1;i<=5;++i)
    51     for (RG int j=1;j<=5;++j) s[i][j]=a[i][j];
    52     for (RG int i=1;i<=8;++i){
    53     if (last+i==9) continue;
    54     x1=x+d1[i],y1=y+d2[i];
    55     if (x1<=0 || x1>5) continue;
    56     if (y1<=0 || y1>5) continue;
    57     swap(s[x][y],s[x1][y1]);
    58     if (go(s,dep)){
    59         dfs(s,x1,y1,dep+1,i);
    60         if (flag) return;
    61     }
    62     swap(s[x][y],s[x1][y1]);
    63     }
    64     return;
    65 }
    66 
    67 il void work(){
    68     for (RG int i=1;i<=5;++i)
    69     for (RG int j=1;j<=5;++j){
    70         x=gc(); if (x=='*') a[i][j]=3,stx=i,sty=j; else a[i][j]=x-48;
    71     }
    72     if (check(a)){ printf("0
    "); return; }
    73     for (d=1;d<=15;++d){
    74     flag=0,dfs(a,stx,sty,0,-1);
    75     if (flag){ printf("%d
    ",d); return; }
    76     }
    77     printf("-1
    "); return;
    78 }
    79 
    80 int main(){
    81     File("knight");
    82     for (RG int i=1;i<=5;++i) goal[1][i]=1;
    83     for (RG int i=2;i<=5;++i) goal[2][i]=1;
    84     goal[3][3]=3,goal[3][4]=goal[3][5]=goal[4][5]=1;
    85     RG int T=gi();
    86     while (T--) work();
    87     return 0;
    88 }
  • 相关阅读:
    Maven关于web.xml中Servlet和Servlet映射的问题
    intellij idea的Maven项目运行报程序包找不到的错误
    修改Maven项目默认JDK版本
    刷题15. 3Sum
    刷题11. Container With Most Water
    刷题10. Regular Expression Matching
    刷题5. Longest Palindromic Substring
    刷题4. Median of Two Sorted Arrays
    刷题3. Longest Substring Without Repeating Characters
    刷题2. Add Two Numbers
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6579336.html
Copyright © 2011-2022 走看看