博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷P2324 [SCOI2005]骑士精神
阅读量:5163 次
发布时间:2019-06-13

本文共 2938 字,大约阅读时间需要 9 分钟。

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。

题目链接:

https://www.luogu.org/problemnew/show/P2324

 

题目描述

 

 

输入输出格式

输入格式:

第一行有一个正整数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

输出样例#1:

7

-1

说明

分析:

这道题用到了迭代加深搜索

或者准确的说是IDA*

但如果这道题用迭代加深+常数优化的话

会跑的更快一些(好吧是因为我不会IDA*

很显然,如果枚举骑士分布,状态巨多,且不好判断空格在哪,所以换个思路,不移骑士,移空格

迭代加深就是每次限制搜索深度,十分广搜

但是,仔细想想,只有四种情况:

1.原来骑士归位了,改完没归位

2.原来骑士没归位,改完归位了

3.原来空位没归位,改完归位了

4.原来空位归位了,改完没归位

参考代码:

 

1 #include 
2 #include
3 #define f(i, a, b) for (i = a; i <= b; ++i) 4 using namespace std; 5 int a[6][6]; 6 int b[6][6] = {
{}, 7 {
0, 1, 1, 1, 1, 1}, 8 {
0, 0, 1, 1, 1, 1}, 9 {
0, 0, 0, -1, 1, 1},10 {
0, 0, 0, 0, 0, 1},11 {
0, 0, 0, 0, 0, 0}};12 int dx[8] = {-2, -2, -1, 1, -1, 1, 2, 2};13 int dy[8] = {-1, 1, 2, 2, -2, -2, -1, 1};14 int mxd;15 inline int read(){16 char ch, c;17 int res = 0;18 while (ch = getchar(), ch < '0' || ch > '9') c = ch;19 res = ch - 48;20 while (ch = getchar(), ch >= '0' && ch <= '9')21 res = (res << 3) + (res << 1) + ch - 48;22 if (c == '-') res = -res;23 return res; 24 }25 int check(int k, int x, int y, int sum, int la){26 if (k + sum > mxd) return 0;27 if (sum == 0) return 1;28 int i, xx, yy, p;29 bool fl = 0, fll = 0;30 f(i, 0, 7){31 if (i != (7 - la)){32 xx = x + dx[i];33 yy = y + dy[i];34 p = sum;35 if (xx <= 5 && xx > 0 && yy <= 5 && yy > 0){36 if (a[xx][yy] == b[xx][yy] && a[xx][yy] != b[x][y]) ++p;37 if (a[xx][yy] != b[xx][yy] && a[xx][yy] == b[x][y]) --p;38 if (b[xx][yy] == -1) --p;39 if (b[x][y] == -1) ++p;40 a[xx][yy] ^= a[x][y], a[x][y] ^= a[xx][yy], a[xx][yy] ^= a[x][y];41 fl = check(k + 1, xx, yy, p, i);42 if (fl) return 1;43 a[xx][yy] ^= a[x][y], a[x][y] ^= a[xx][yy], a[xx][yy] ^= a[x][y];44 }45 }46 }47 return 0;48 }49 int main(){50 int i, j, t;51 char k;52 scanf("%d", &t);53 while (t){54 int mn = 0, x, y;55 f(i, 1, 5)56 f(j, 1, 5){57 cin >> k;58 if (k == '*'){59 a[i][j] = -1;60 x = i, y = j;61 }62 else a[i][j] = k - '0';63 if (a[i][j] != b[i][j]) mn++;64 }65 bool fl = 0;66 f(i, mn, 16){67 mxd = i;68 if (check (0, x, y, mn, -1)){69 printf("%d\n", i - 1), fl = 1; break;70 }71 }72 if (!fl)73 printf("-1\n");74 t--;75 }76 return 0;77 }

 

转载于:https://www.cnblogs.com/ylyvictor/p/8466341.html

你可能感兴趣的文章
Java中反射的学习与理解(一)
查看>>
C语言初学 俩数相除问题
查看>>
B/S和C/S架构的区别
查看>>
[Java] Java record
查看>>
jQuery - 控制元素显示、隐藏、切换、滑动的方法
查看>>
postgresql学习文档
查看>>
Struts2返回JSON数据的具体应用范例
查看>>
js深度克隆对象、数组
查看>>
socket阻塞与非阻塞,同步与异步
查看>>
团队工作第二天
查看>>
System类
查看>>
tableView
查看>>
Happy Great BG-卡精度
查看>>
Xamarin Visual Studio不识别JDK路径
查看>>
菜鸟“抄程序”之道
查看>>
Ubuntu下关闭防火墙
查看>>
TCP/IP 邮件的原理
查看>>
原型设计工具
查看>>
windows下的C++ socket服务器(4)
查看>>
css3 2d转换3d转换以及动画的知识点汇总
查看>>