Bzoj 1085: [SCOI2005]骑士精神 (dfs)

Bzoj 1085: [SCOI2005]骑士精神

题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1085
dfs + 剪枝.
剪枝方法:
1.每次交换只能改变一个位置.若发现之间相差的步数加上以前走的步数大于15的话,直接舍弃这一状态.
2.初始时,\(ans\)设为\(16\)
有了上面两个剪枝就A了.
照这节奏,SCOI2005就刷完了???

#include <iostream>
#include <cstdio>
#define X 6
using namespace std;

const int gx[] = {0,-2,-2,-1,-1,1,1,2,2};
const int gy[] = {0,-1,1,-2,2,-2,2,-1,1};

char map[X][X];
char c[X][X] = {
    '0','0','0','0','0','0',
    '0','1','1','1','1','1',
    '0','0','1','1','1','1',
    '0','0','0','*','1','1',
    '0','0','0','0','0','1',
    '0','0','0','0','0','0'
};

int ans;

int inint(){
    int num = 0;
    for(int i = 1;i <= 5;++ i){
        for(int j = 1;j <= 5;++ j){
            if(c[i][j] != map[i][j])num ++;
        }
    }
    return num;
}

void dfs(int x,int y,int d,int tmp){
    int l = inint();
    if(d + l > 16)return;
    if(d > ans)return;
    if(l == 0) ans = d;

    for(int i = 1;i <= 8;++ i){
        if(x + gx[i] < 1 || x + gx[i] > 5)continue;
        if(y + gy[i] < 1 || y + gy[i] > 5)continue;
        if(tmp + i == 9)continue;
        swap(map[x][y],map[x + gx[i]][y + gy[i]]);
        dfs(x + gx[i],y + gy[i],d + 1,i);
        swap(map[x][y],map[x + gx[i]][y + gy[i]]);
    }
}

void work(){
    int x,y;
    for(int i = 1;i <= 5;++ i)cin >> map[i] + 1;
    for(int i = 1;i <= 5;++ i){
        for(int j = 1;j <= 5;++ j){
            if(map[i][j] == '*')
                x = i,y = j;
        }
    }
    ans = 16;
    dfs(x,y,0,0);
    printf("%d\n",ans == 16 ? -1 : ans);
    return;
}

int main(){
    int t;
    scanf("%d",&t);
    while(t --){
        work();
    }
    return 0;
}

原文地址:https://www.cnblogs.com/tpgzy/p/9726569.html

时间: 2024-10-12 03:09:55

Bzoj 1085: [SCOI2005]骑士精神 (dfs)的相关文章

BZOJ 1085: [SCOI2005]骑士精神( IDDFS + A* )

一开始写了个 BFS 然后就 T 了... 这道题是迭代加深搜索 + A* ------------------------------------------------------------------------------ #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define rep( i , n ) for( int i = 0 ; i

[BZOJ 1085] [SCOI2005] 骑士精神 [ IDA* 搜索 ]

题目链接 : BZOJ 1085 题目分析 : 本题中可能的状态会有 (2^24) * 25 种状态,需要使用优秀的搜索方式和一些优化技巧. 我使用的是 IDA* 搜索,从小到大枚举步数,每次 DFS 验证在当前枚举的步数之内能否到达目标状态. 如果不能到达,就枚举下一个步数,重新搜索,即使某些状态在之前的 DFS 中已经搜索过,我们仍然搜索. 并且在一次 DFS 中,我们不需要判定重复的状态. 在 IDA* 中,重要的剪枝优化是 估价函数 ,将一些不可能存在可行解的枝条剪掉. 如果估价函数写得

[BZOJ 1085][SCOI2005]骑士精神(IDA*)

题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1085 分析: 首先第一感觉是宽搜,但是空间需要8^15*5*5,明显不够,又鉴于最大深度为15,所以可以用迭代加深做. 但是普通的迭代加深还是会TLE.于是考虑加上估价函数 设当前层数的上界为Kmax,当前搜索的层数为K,我们知道一次移动顶多改变目前矩阵和目标矩阵的一个差别,于是可以求出当前与目标矩阵不同的位置的个数s,如果k+s>Kmax那么就可以直接不做了.

bzoj 1085: [SCOI2005]骑士精神 IDA*

题目链接 给一个图, 目标位置是确定的, 问你能否在15步之内达到目标位置. 因为只有15步, 所以直接ida* #include<bits/stdc++.h> using namespace std; #define pb(x) push_back(x) #define ll long long #define mk(x, y) make_pair(x, y) #define lson l, m, rt<<1 #define mem(a) memset(a, 0, sizeof(

BZOJ 1085 [SCOI2005]骑士精神

据说是A_star的裸题,感觉就是爆搜剪枝. //Twenty #include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<queue> #include<vector> using namespace std; int ans,T,x,y

【BZOJ】1085: [SCOI2005]骑士精神

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1085 $${if (cs+val-1>ans) return ;}$$ 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #inc

bzoj1085 [SCOI2005]骑士精神

1085: [SCOI2005]骑士精神 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2490  Solved: 1422[Submit][Status][Discuss] Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空位上. 给定一个初始的棋盘,怎样才能经过移动

【bzoj1085】[SCOI2005]骑士精神

1085: [SCOI2005]骑士精神 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1757  Solved: 961[Submit][Status][Discuss] Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空位上. 给定一个初始的棋盘,怎样才能经过移动变

洛谷 P2324 [SCOI2005]骑士精神

P2324 [SCOI2005]骑士精神 题目描述 输入输出格式 输入格式: 第一行有一个正整数T(T<=10),表示一共有N组数据.接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,*表示空位.两组数据之间没有空行. 输出格式: 对于每组数据都输出一行.如果能在15步以内(包括15步)到达目标状态,则输出步数,否则输出-1. 输入输出样例 输入样例#1: 2 10110 01*11 10111 01001 00000 01011 110*1 01110 01010 00100 输出样例