uva10422

题目大意:
跟国际象棋中的骑士的走法差不多,是走日字型的。找到空格,从空格开始走,这题是用回溯+剪枝做的。计算它没有达到目标位置的数量,如果数量等于0的话就用一个变量保存下来值与其他同样满足的值进行比较。如果不等于0的话,它每走一步最多改变的是两个位置的状态,那么如果走了(sum+1)/2+step 是所需要走的最少的步数如果大于原来的最少值的话 就直接返回。(这一步是很重要的剪枝)

代码:

#include <iostream>
using namespace std;
#include <cstring>
#include <stdio.h>
#include <queue>

//int grid[5][5];

//queue<int> q;
int _min;
int des[5][5] = {{1,1,1,1,1},{0,1,1,1,1},{0,0,2,1,1},{0,0,0,0,1},{0,0,0,0,0,}};
int grid[5][5];
//int move[8][2] = {{1,2},{-1,2},{2,1},{2,-1},{-2,1},{-2,-1},{1,-2},{-1,-2}};
int move1[8][2]={{-1,-2},{-1,2},{-2,1},{-2,-1},{2,1},{2,-1},{1,-2},{1,2}};
void dfs(int x,int y,int step,int pos) {
// cout << "1" ;
    int sum = 0,temp,x1,y1;
    if(step >= _min)
        return;
    for(int i = 0 ; i < 5; i++) 
        for(int j = 0 ; j < 5; j++)
            if(grid[i][j] != des[i][j]) 
                ++sum;
// printf("%d ",sum);
    if(sum == 0) {
        if(step < _min)
            _min = step;
        //printf("1");
        return;
    }
    if((sum+1)/2 + step >= _min)
        return;
    for(int i = 0; i < 8; i++) {
         x1 = x + move1[i][0];
         y1 = y + move1[i][1];
        if((x1 >= 0) && (x1 <5) && (y1 >=0) && (y1 <5) && ((pos+i) != 7)) {
            temp = grid[x1][y1];
            grid[x1][y1] = grid[x][y];
            grid[x][y] = temp;
            dfs(x1,y1,step+1,i);
            temp = grid[x1][y1];
            grid[x1][y1] = grid[x][y];
            grid[x][y] = temp;
        }
    }

}

int main() {
    int T;
    scanf("%d",&T);
    getchar();
    char s[6];
    int x,y;
    while(T--) {
        for(int i = 0 ; i < 5; i++) {
            gets(s);
            for(int j = 0 ; s[j]!= '\0'; j++) {
                if(s[j] == ' ') {
                    x = i; 
                    y = j;
                    grid[i][j] = 2;
                }
                else 
                    grid[i][j] = s[j] -'0'; 
    // printf("%d",grid[i][j]);
            }
    // cout <<endl;
        }
        _min = 11;
        dfs(x,y,0,8);   
        if(_min  > 10) 
            printf("Unsolvable in less than 11 move(s).\n");
        else
            printf("Solvable in %d move(s).\n",_min);
    }
    return 0;
}

你可能感兴趣的:(uva10422)