求问个算法有关问题,题目如下
求问个算法问题,题目如下
硬解我能解出来 但是总是超时 实在想不出什么优化的算法了
http://oj.hi-hi.cn/JudgeOnline/problem.php?cid=1117&pid=10
------解决思路----------------------
超时是必须的:
等楼下高手改动态规划中……
硬解我能解出来 但是总是超时 实在想不出什么优化的算法了
http://oj.hi-hi.cn/JudgeOnline/problem.php?cid=1117&pid=10
------解决思路----------------------
//问题 K: 清障碍
//时间限制: 4 Sec 内存限制: 32 MB
//题目描述
//游戏是一个5行4列的方格阵列,有些格子有障碍物,有些没有,过关是要求所有的障碍物被清除.
//Ada只能在没有障碍物的格子放置炸弹, 炸弹会清除东南西北四个方向上的相邻格子的障碍物.
//也就是,如果无障碍物的格子座标是(x,y), 则(x+1, y),(x-1,y),(x,y+1),(x,y-1)四个相邻格
//的障碍物(如果有的话)都会清除, 座标越界的情况不需要考虑.
//为了挽救沉迷游戏的Ada, 规定Ada每过一关必须用最少的炸弹,否则就收缴手机让她没得玩.
//如下图的局面(1表示障碍),只需要一个炸弹即可
//0000
//0100
//1010
//0100
//0000
//显然Ada处理不了这么复杂的问题,帮帮她吧
//输入
// 由不超过20000组测试数据组成,格式参见样例. 每组测试数据的第一行是"Case 编号:"的形式,
// 随后有5行4列的方格阵,0表示格子无障碍,1表示有障碍. 保证不会出现格子全部都是障碍的清空.
//输出
// 每组数据输出一行,包含清除所有障碍所需要的最少炸弹数目,格式参见样例.
//
//样例输入
//Case 1:
//1000
//0000
//0000
//0000
//0000
//Case 2:
//1100
//0000
//0000
//0000
//0000
//Case 3:
//1010
//0000
//0000
//0000
//0000
//样例输出
//The result of case 1 is 1
//The result of case 2 is 2
//The result of case 3 is 1
//
//思路:
//保存现场
//测试下一个1旁边的0
//模拟爆炸
//若全0,记录本轮共炸几次,恢复现场,递归
//若非全0,递归
#include <stdio.h>
#include <string.h>
int minb;
int ok(int y,int x) {
if (0<=y && y<5 && 0<=x && x<4) return 1;
else return 0;
}
int clean(char m[5][6]) {
int y,x;
for (y=0;y<5;y++) {
for (x=0;x<4;x++) {
if ('0'!=m[y][x]) return 0;
}
}
return 1;
}
void bomb(char m[5][6],int y,int x,char n[5][6]) {
memcpy((void *)n,(void *)m,30);
if (ok(y-1,x)) n[y-1][x]='0';
if (ok(y+1,x)) n[y+1][x]='0';
if (ok(y,x-1)) n[y][x-1]='0';
if (ok(y,x+1)) n[y][x+1]='0';
}
void bomball(char m[5][6],int b) {//b为已放炸弹总数
char c;
char M[5][6];
char N[5][6];
int y,x,d,yy,xx;
memcpy((void *)M,(void *)m,30);
for (y=0;y<5;y++) {
for (x=0;x<4;x++) {
c=M[y][x];
if ('0'!=c) {
for (d=0;d<4;d++) {
switch (d) {
case 0:yy=y-1;xx=x;break;
case 1:yy=y+1;xx=x;break;
case 2:yy=y;xx=x-1;break;
case 3:yy=y;xx=x+1;break;
}
if (ok(yy,xx)) {
c=M[yy][xx];
if ('0'==c) {
b++;
bomb(M,yy,xx,N);
if (clean(N)) {
if (b<minb) minb=b;
b--;
} else {
memcpy((void *)M,(void *)N,30);
bomball(M,b);
}
}
}
}
}
}
}
if (b<minb) minb=b;
}
int main() {
char ln[16];
int n;
char c;
char m[5][6];
int y;
while (1) {
if (NULL==fgets(ln,16,stdin)) break;
if ('\n'==ln[0]) break;
if (2!=sscanf(ln,"Case %d%c",&n,&c)) break;
if (':'!=c) break;
for (y=0;y<5;y++) {
if (NULL==fgets(m[y],6,stdin)) break;
}
if (y<5) break;
minb=20;
bomball(m,0);
printf("The result of case %d is %d\n",n,minb);
}
return 0;
}
等楼下高手改动态规划中……