zoukankan      html  css  js  c++  java
  • [bzoj1805][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
     

    My Solution

    启发式搜索膜版题
    %%%
    关于check(state)该不该存在一直很疑惑
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 using namespace std;
     5 
     6 //目标态
     7 int fin[5][5]={{1,1,1,1,1},
     8                {2,1,1,1,1},
     9                {2,2,0,1,1},
    10                {2,2,2,2,1},
    11                {2,2,2,2,2}};
    12 int dirx[8]={-1,-1,-2,-2,1,1,2,2};
    13 int diry[8]={-2,2,-1,1,-2,2,-1,1};
    14 
    15 struct State{
    16     int a[5][5];
    17 };
    18 
    19 bool check(const State &st){
    20     for(int i=0;i<5;i++)
    21         for(int j=0;j<5;j++)
    22             if(st.a[i][j]!=fin[i][j])  return 0;
    23     return 1;
    24 }
    25 
    26 int H(const State &st){
    27     int ret=0;
    28     for(int i=0;i<5;i++)
    29         for(int j=0;j<5;j++)
    30             if(st.a[i][j]!=fin[i][j])  ret++;
    31     return ret;
    32 }
    33 
    34 bool ok;
    35 int lim;
    36 
    37 void dfs(State st,int x,int y,int g){
    38     if(g==lim){
    39         if(check(st))  ok=1;
    40         return ;
    41     }
    42     if(ok)  return;
    43     for(int i=0;i<8;i++){
    44         int xx=x+dirx[i],yy=y+diry[i];
    45         if(xx<0||xx>4||yy<0||yy>4)  continue;
    46         swap(st.a[x][y],st.a[xx][yy]);
    47         if(H(st)+g<=lim)  dfs(st,xx,yy,g+1);
    48         swap(st.a[x][y],st.a[xx][yy]);
    49     }
    50 }
    51 
    52 int t;
    53 State st;
    54 char ch[5];
    55 
    56 int main(){
    57     //freopen("temp.in","r",stdin);
    58     scanf("%d",&t);
    59     while(t--){
    60         int x,y;
    61         for(int i=0;i<5;i++){
    62             scanf("%s",ch);
    63             for(int j=0;j<5;j++){
    64                 if(ch[j]=='1')
    65                     st.a[i][j]=1;
    66                 if(ch[j]=='0')
    67                     st.a[i][j]=2;
    68                 if(ch[j]=='*'){
    69                     st.a[i][j]=0;
    70                     x=i,y=j;
    71                 }
    72             }
    73         }
    74         ok=0;
    75         for(lim=1;lim<=15;lim++){
    76             dfs(st,x,y,0);
    77             if(ok){
    78                 printf("%d
    ",lim);
    79                 break;
    80             }
    81         }
    82         if(!ok)
    83             printf("-1
    ");
    84     }
    85     return 0;
    86 }

    他们在别有用心的生活里 翩翩舞蹈

  • 相关阅读:
    2. Add Two Numbers
    1. Two Sum
    leetcode 213. 打家劫舍 II JAVA
    leetcode 48. 旋转图像 java
    leetcode 45. 跳跃游戏 II JAVA
    leetcode 42. 接雨水 JAVA
    40. 组合总和 II leetcode JAVA
    24. 两两交换链表中的节点 leetcode
    1002. 查找常用字符 leecode
    leetcode 23. 合并K个排序链表 JAVA
  • 原文地址:https://www.cnblogs.com/ZYBGMZL/p/6853030.html
Copyright © 2011-2022 走看看