城堡

 

城堡

Time Limit: 1 Seconds     Memory Limit: 32768 K

Total Submit:18     Accepted:4


Description

 


Figure 1 是一个3行6列的共18个空间的城堡的地图.写一个程序计算如下问题
1、有几条最短的路走出这个城堡。
2、这几个最短的路总共有几步。
3、标记所有可以用最短路走出路线。
我们假设这个城堡被分成m*n的空间(m<=50,m<=50),至少有一个空间。 每个空间可由1至4面墙包围。

Input

你将读入多组数据直到文件结束。对于每组数据,第一行为m,n,对于接下来的几行,读入一个m*n的矩阵,矩阵上每个数p(0<=p<=15)代表着城堡相应空间里四面墙的权值之和,即相应空间的某个方向存在墙,则加上该墙的权值,四面墙的权值分别为:1(西墙), 2(北墙),4(东墙),8(南墙)。城堡至少有一个空间。
城堡只有一个入口和出口。
我们保证城堡的入口一定在西面,出口一定在东面,如Figure 1所示

Output

对于每组测试数据,第一行为"Case #n:",其中n是第几组数据。第二行,如果能走出城堡,则输出有几条最短路径"We could get out of the castle by d shortest ways!",其中d为最短路径条数,如果d==1请用"way"代替"ways",紧接着输出最短路径的步数"The shortest way contains k steps.",其中k为步数,如果k==1请用"step"代替"steps"。如果不能走出城堡,则输出"We couldn't get out of the castle~"。最后,输出该城堡的地图,如果能走出城堡,还要用'M'标出所有能走出城堡的最短路径。
每组测试数据后面请输出一个空行。

Sample Input

 

1 1
10
3 6
7 7 11 6 3 6
8 0 10 8 0 4
15 13 15 15 9 8
5 5
10 6 3 6 11
11 8 8 8 6
15 3 6 11 12
11 4 5 11 6
15 13 9 10 12

 

Sample Output

 

Case #1:
We could get out of the castle by 1 shortest way!
The shortest way contains 1 step.
#####
| M |
#####

Case #2:
We could get out of the castle by 2 shortest ways!
The shortest way contains 7 steps.
#########################
#   #   #   |   #   |   #
#---#---#####---#---#---#
| M | M | M | M | M | M #
#####---#########---#---#
#   #   #   #   # M | M |
#########################

Case #3:
We couldn't get out of the castle~
#####################
|   |   #   |   #   |
#####---#---#---#####
#   |   |   |   |   #
#################---#
#   #   |   #   |   #
#####---#---#########
#   |   #   #   |   #
#####---#---#####---#
#   #   #   |   |   #
#####################

 

Source

PhoenixWright@fjnu

下面是本人有点偷懒的算法(最后输出的地方不画城堡了 用0,1代表)

#include <iostream>

using namespace std;

struct chengbao
{
int m, n;
int* quan;
};
chengbao cb;

struct step
{
int m,n;
step* next;
};

struct Paths
{
step* s;
int count;
};
Paths* paths = new Paths;

struct resultPath
{
int *ditu;
int count;
int ways;
};
resultPath rp;

void outputmap()
{
cout<<endl;

if (rp.ways == 0)
{
   cout<<"We couldn't get out of the castle~"<<endl;
  
}
else
{
   if (rp.count == 1)
   {
    cout<<"We could get out of the castle by 1 shortest way!"<<endl;
    cout<<"The shortest way contains 1 step."<<endl;
   }
   else
   {
    cout<<"We could get out of the castle by "<< rp.ways <<" shortest way!"<<endl;
    cout<<"The shortest way contains " << rp.count<< " step."<<endl;
   }
}
for (int i=0; i<cb.m; i++)
{
   for (int j=0; j<cb.n; j++)
   {
    cout<<rp.ditu[i*cb.n + j]<<" ";
   }
   cout<<endl;
}
}

void output()
{
if (paths->count-1 > rp.count) return;

if (paths->count < rp.count)
{
   for (int i=0; i<cb.m; i++)
   {
    for (int j=0; j<cb.n; j++)
    {
     rp.ditu[i*cb.n + j] = 0;
    }
   }
   rp.ways = 0;
}

rp.ways++;
rp.count =paths->count-1;
step* ss = paths->s;
while (ss->next != NULL)
{
   rp.ditu[ss->m*cb.n + ss->n] = 1;
   ss = ss->next;
}
}

void SelectPath(step *s)
{
if (s->n >= cb.n) //out
{
   output();
   return;
}

if (s->n < 0)
{
   return;
}

if (cb.quan[s->m*cb.n + s->n] >= 100) //has walk
{
   return;
}

paths->count++;
cb.quan[s->m*cb.n + s->n] += 100; //signed walk
step *newstep = new step;
newstep->m = s->m;
newstep->n = s->n;
newstep->next = NULL;

int quan = cb.quan[s->m * cb.n+ s->n]%100;
if (quan < 8) //nan //if no wall, go!
{
   newstep->m += 1;
   s->next = newstep;
  
   SelectPath(newstep);
  
   newstep->m -= 1;
}
quan = quan%8;

if (quan < 4) //dong
{
   newstep->n += 1;
   s->next = newstep;

   SelectPath(newstep);

   newstep->n -= 1;
}
quan = quan%4;

if (quan < 2) //bei
{
   newstep->m -= 1;
   s->next = newstep;

   SelectPath(newstep);

   newstep->m += 1;
}
quan = quan%2;

if (quan != 1) //xi
{
   newstep->n -= 1;
   s->next = newstep;

   SelectPath(newstep);
}

cb.quan[s->m*cb.n + s->n] -= 100;

if (newstep->next == NULL && newstep->n < cb.n) //if no next and no out, then delete
{
   delete newstep;
   s->next = newstep = NULL;
   paths->count--;
}

}

void release()
{
step* ss = paths->s;
step* ss1 = NULL;
while (ss!=NULL)
{
   ss1 = ss;
   ss = ss->next;
   delete ss1;
}

delete paths;
delete cb.quan;
delete rp.ditu;
}

int main()
{
rp.count = 10000;
rp.ways = 0;
paths->s = NULL;
paths->count = 0;
cin>>cb.m>>cb.n;
cb.quan = new int[cb.m * cb.n];
rp.ditu = new int[cb.m * cb.n]; //map signed

int i,j;
for (i=0; i<cb.m; i++) //init
{
   for (j=0; j<cb.n; j++)
   {
    cin>>cb.quan[i*cb.n + j];
    rp.ditu[i*cb.n + j] = 0;
   }
}

step *lukou = new step;
for (i=0; i<cb.m; i++) //select in
{
   if (cb.quan[i*cb.m]%2 != 1)
   {
    lukou->m = i;
    lukou->n = 0;
    lukou->next = NULL;
    paths->s = lukou;
    break;
   }
}

SelectPath(lukou);
outputmap();

release();
cin.get();
cin.get();
return 0;
}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值