①用C语言实现
#include<stdio.h>
#define MAX 4
#define WALL -1
char map[MAX+2][MAX+2];
int size,max,cur,depth;
void test(){
int i =depth/size +1, j =depth%size +1,n;
if(depth>=size*size){
if(cur>max) max =cur;
return;
}
if(!map[i][j]){
map[i][j] =1;
for(n=i+1;map[n][j]!=WALL;n++) map[n][j]++;
for(n=i-1;map[n][j]!=WALL;n--) map[n][j]++;
for(n=j+1;map[i][n]!=WALL;n++) map[i][n]++;
for(n=j-1;map[i][n]!=WALL;n--) map[i][n]++;
depth++;
cur++;
test();
cur--;
depth--;
for(n=i+1;map[n][j]!=WALL;n++) map[n][j]--;
for(n=i-1;map[n][j]!=WALL;n--) map[n][j]--;
for(n=j+1;map[i][n]!=WALL;n++) map[i][n]--;
for(n=j-1;map[i][n]!=WALL;n--) map[i][n]--;
map[i][j] =0;
}
depth++;
test();
depth--;
}
void main(){
int i,j;
while(scanf_s("%d",&size)!=EOF&&size>0){
getchar();
for(i=0;i<=size+1;i++)
map[0][i] =map[size+1][i] =map[i][0] =map[i][size+1] =WALL;//四面都是墙
for(i=1;i<=size;i++){
for(j=1;j<=size;j++) map[i][j] = (getchar()=='X')?WALL:0;//输入内部构造
getchar();
}
max =cur =depth =0;
test();
printf("%d/n",max);
}
}
②用C++实现标准库实现
#include <iostream>
#include <vector>
#include <string>
using namespace std;
enum Tag
{
STREET=0,
VISITED=1,
WALL=2,
ERROR=-1
};
{
public:
int x;
int y;
};
{
switch(ch)
{
case '.':
return STREET; //street
break;
case 'X':
return WALL; //wall
break;
default:
return ERROR; //wrong input
break;
}
}
{
for(int row=0;row<n;row++)
{
vector<int> r(n);
string line;
cin>>line;
for(int col=0;col<n;col++)
r[col]=Transfer(line[col]);
map.push_back(r);
}
}
{
int size=map.size();
//backward
for(int b=j-1;b>=0;b--)
{
if(map[i][b]==WALL)
{
break;
}
else if(map[i][b]==STREET)
{
map[i][b]=VISITED;
Point pt;
pt.x=i;
pt.y=b;
pvec.push_back(pt);
}
}
for(int f=j+1;f<size;f++)
{
if(map[i][f]==WALL)
{
break;
}
else if(map[i][f]==STREET)
{
map[i][f]=VISITED;
Point pt;
pt.x=i;
pt.y=f;
pvec.push_back(pt);
}
}
//up
for(int u=i-1;u>=0;u--)
{
if(map[u][j]==WALL)
{
break;
}
else if(map[u][j]==STREET)
{
map[u][j]=VISITED;
Point pt;
pt.x=u;
pt.y=j;
pvec.push_back(pt);
}
}
for(int d=i+1;d<size;d++)
{
if(map[d][j]==WALL)
{
break;
}
else if(map[d][j]==STREET)
{
map[d][j]=VISITED;
Point pt;
pt.x=d;
pt.y=j;
pvec.push_back(pt);
}
}
}
{
for(int k=0;k<pvec.size();k++)
{
Point pt=pvec[k];
map[pt.x][pt.y]=STREET;
}
}
{
int size=map.size();
for(int i=0;i<size;i++)
for(int j=0;j<size;j++)
if(map[i][j]==STREET)
return true;
return false;
}
{
if(!FindStreet(map))
{
max=max>count?max:count;
return;
}
int size=map.size();
for(int i=0;i<size;i++)
{
for(int j=0;j<size;j++)
{
if(map[i][j]==STREET)
{
map[i][j]=VISITED;
count++;
vector<Point> pvec;
Scan(map, i, j, pvec);
map[i][j]=STREET;
count--;
ResetScan(map, pvec);
}
}
}
}
{
int n;
cin>>n;
while(n!=0)
{
vector< vector<int> > Map;
Readin(Map,n);
int max=0;
DFS(Map, max, count);
}
return 0;
}
这里使用DFS来做。只适合于问题规模不大的情况。
另外也可以使用二分图的匹配方法来做,时间复杂度要低。
③用C++队列实现
#i nclude<iostream>
#i nclude<math.h>
using std::cout;
using std::endl;
using std::cin;
//0 空格 1 被射击 2 房子 3 墙
struct CiteSite
{
int x,y; //方格中的位置
CiteSite(){}
CiteSite(int i,int j){x=i;y=j;}
};
struct CityPic
{
unsigned long Buf[2]; //用来压缩方格
CityPic(){};
CityPic(const CityPic &item){Buf[0]=item.Buf[0];Buf[1]=item.Buf[1];}
};
struct CityPics
{
int M; //M*M
CityPic citypic;
};
template<class NodeEntry>
struct Node
{
Node():Next(NULL){}
Node(const NodeEntry &entry):Entry(entry){}
NodeEntry Entry;
Node *Next;
};
template<class NodeEntry>
class Queue
{
public:
Queue(); //构造函数
~Queue(); //析构函数
bool IsEmpty() const; //队列是否为空
NodeEntry Server(); //返回并去掉队首元素
void Append(const NodeEntry &item); //添加一个队尾元素
void Retrieve(NodeEntry &item) const; //取得队首元素
int Size()const; //队列现有元素个数
void Clear(); //队列清空
int iCount;
Node<NodeEntry> *Front,*Rear;
};
void GetCity(char Buf[][4],int M); //读取输入的方格
void InCode(CityPic& citypic,char Buf[][4]); //方格编码
void OutCode(CityPic &citypic,char Buf[][4]); //方格解码
void CopyBuf(char Buf[][4],char OldBuf[][4]); //复制方格
int SeachCity(char Buf[][4],int M,Queue<CiteSite> &CitySiteQueue);//将可建房的位置装入CitySiteQueue
bool IsCityPicInQueue(CityPic& citypic,Queue<CityPic> &queue); //队列中是否存在该方格的编码
bool IsCityPicCanBeExpand(char Buf[][4],int M); //该方格是否可扩展
void ExpandCityPic(char Buf[][4],int x,int y,int M); //扩展方格
int CountHouse(char Buf[][4],int M); //计算方格中的房子数量
/***************************************************************************************/
/****************************************************************************************/
int main()
{
CityPic citypic; //方格编码
Queue<CityPic> queue; //方格编码队列
CityPics citypics; //带M的方格编码
Queue<CityPics> CityPicsQueue;//带M的方格编码队列
CiteSite citysite; //方格中的位置坐标
Queue<CiteSite> CitySiteQueue;//坐标队列
bool bWorking=true; //是否进行方格处理
char OldCityBuf[4][4]={0};
char CityBuf[4][4]={0};
int M;
cin>>M;
while(M!=0)
{
GetCity(OldCityBuf,M);
InCode(citypics.citypic,OldCityBuf);
citypics.M=M; //输入 带M的方格编码到CityPicsQueue
CityPicsQueue.Append(citypics);
cin>>M;
}
while(CityPicsQueue.iCount>0)
{
citypics=CityPicsQueue.Server();
M=citypics.M;
OutCode(citypics.citypic,OldCityBuf); //取得原始方格
if(!IsCityPicCanBeExpand(OldCityBuf,M))
{
cout<<0<<endl;
continue;
}
bWorking=true;
while(bWorking)
{
SeachCity(OldCityBuf,M,CitySiteQueue);//装入坐标队列
while(CitySiteQueue.iCount>0)
{
citysite=CitySiteQueue.Server();
CopyBuf(CityBuf,OldCityBuf);
ExpandCityPic(CityBuf,citysite.x,citysite.y,M);//扩展
if(!IsCityPicCanBeExpand(CityBuf,M))
{
if(queue.iCount==0&&CitySiteQueue.iCount<=0)
{
bWorking=false;
cout<<CountHouse(CityBuf,M)<<endl;
break;
}
else continue;
}
InCode(citypic,CityBuf);//编码
if(IsCityPicInQueue(citypic,queue))
{
continue;
}
queue.Append(citypic); //编码入队
}
if(bWorking)
{
citypic=queue.Server(); //取新编码
OutCode(citypic,OldCityBuf);//解码
}
}
}
return 0;
}
/**************************************************************************************/
/**************************************************************************************/
void GetCity(char Buf[][4],int M)
{
char c;
memset(Buf,16,0);
for(int i=0;i<M;i++)
for(int j=0;j<M;j++)
{
cin>>c;
if(c=='.') Buf[i][j]=0;
else Buf[i][j]=3;
}
}
void InCode(CityPic& citypic,char Buf[][4])
{
memset(&citypic,sizeof(CityPic),0);
citypic.Buf[0]=Buf[0][0]+
Buf[0][1]*10+
Buf[0][2]*100+
Buf[0][3]*1000+
Buf[1][0]*10000+
Buf[1][1]*100000+
Buf[1][2]*1000000+
Buf[1][3]*10000000+
Buf[2][0]*100000000;
citypic.Buf[1]=Buf[2][1]+
Buf[2][2]*10+
Buf[2][3]*100+
Buf[3][0]*1000+
Buf[3][1]*10000+
Buf[3][2]*100000+
Buf[3][3]*1000000;
}
void OutCode(CityPic &citypic,char Buf[][4])
{
memset(Buf,16,0);
Buf[0][0]=citypic.Buf[0]%10;
citypic.Buf[0]/=10;
Buf[0][1]=citypic.Buf[0]%10;
citypic.Buf[0]/=10;
Buf[0][2]=citypic.Buf[0]%10;
citypic.Buf[0]/=10;
Buf[0][3]=citypic.Buf[0]%10;
citypic.Buf[0]/=10;
Buf[1][0]=citypic.Buf[0]%10;
citypic.Buf[0]/=10;
Buf[1][1]=citypic.Buf[0]%10;
citypic.Buf[0]/=10;
Buf[1][2]=citypic.Buf[0]%10;
citypic.Buf[0]/=10;
Buf[1][3]=citypic.Buf[0]%10;
citypic.Buf[0]/=10;
Buf[2][0]=citypic.Buf[0]%10;
Buf[2][1]=citypic.Buf[1]%10;
citypic.Buf[1]/=10;
Buf[2][2]=citypic.Buf[1]%10;
citypic.Buf[1]/=10;
Buf[2][3]=citypic.Buf[1]%10;
citypic.Buf[1]/=10;
Buf[3][0]=citypic.Buf[1]%10;
citypic.Buf[1]/=10;
Buf[3][1]=citypic.Buf[1]%10;
citypic.Buf[1]/=10;
Buf[3][2]=citypic.Buf[1]%10;
citypic.Buf[1]/=10;
Buf[3][3]=citypic.Buf[1]%10;
}
void CopyBuf(char Buf[][4],char OldBuf[][4])
{
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
Buf[i][j]=OldBuf[i][j];
}
int SeachCity(char Buf[][4],int M,Queue<CiteSite> &CitySiteQueue)
{
int r=0;
for(int i=0;i<M;i++)
for(int j=0;j<M;j++)
{
if(Buf[i][j]==0)
{
r++;
CitySiteQueue.Append(CiteSite(i,j));
}
}
return r;
}
bool IsCityPicInQueue(CityPic& citypic,Queue<CityPic>&queue)
{
Node<CityPic> *pNode=queue.Front;
int i=queue.iCount;
while(i>0)
{
if((citypic.Buf[0]==pNode->Entry.Buf[0])&&(citypic.Buf[1]==pNode->Entry.Buf[1]))
return true;
pNode=pNode->Next;
i--;
}
return false;
}
bool IsCityPicCanBeExpand(char Buf[][4],int M)
{
for(int i=0;i<M;i++)
for(int j=0;j<M;j++)
{
if(Buf[i][j]==0)
return true;
}
return false;
}
void ExpandCityPic(char Buf[][4],int x,int y,int M)
{
int i=x,j=y;
Buf[x][y]=2;
while(i>0)
{
if(Buf[i-1][y]!=3)
Buf[i-1][y]=1;
else break;
i--;
}
i=x;
while(i<M-1)
{
if(Buf[i+1][y]!=3)
Buf[i+1][y]=1;
else break;
i++;
}
j=y;
while(j>0)
{
if(Buf[x][j-1]!=3)
Buf[x][j-1]=1;
else break;
j--;
}
j=y;
while(j<M-1)
{
if(Buf[x][j+1]!=3)
Buf[x][j+1]=1;
else break;
j++;
}
}
int CountHouse(char Buf[][4],int M)
{
int r=0;
for(int i=0;i<M;i++)
for(int j=0;j<M;j++)
{
if(Buf[i][j]==2)
r++;
}
return r;
}
/***********************************构造函数*******************************************/
template<class NodeEntry>
Queue<NodeEntry>::Queue()
{
iCount=0;
Front=Rear=NULL;
}
/***********************************析构函数*******************************************/
template<class NodeEntry>
Queue<NodeEntry>::~Queue()
{
Clear();
}
/***********************************队列是否为空***************************************/
template<class NodeEntry>
bool Queue<NodeEntry>::IsEmpty() const
{
return (iCount==0);
}
/*********************************返回并去掉队首元素**********************************/
template<class NodeEntry>
NodeEntry Queue<NodeEntry>::Server()
{
NodeEntry entry;
if(Front==NULL)cout<<"The Queue is empty!/n";
Node<NodeEntry> *pNode=Front;
Front=Front->Next;
entry=pNode->Entry;
delete pNode;
iCount--;
if(iCount<=0) Front=Rear=NULL;
return entry;
}
/*********************************添加一个队尾元素************************************/
template<class NodeEntry>
void Queue<NodeEntry>::Append(const NodeEntry &item)
{
Node<NodeEntry> *pNode=new Node<NodeEntry>(item);
if(Rear==NULL) Front=Rear=pNode;
else
{
Rear->Next=pNode;
Rear=pNode;
}
iCount++;
}
/********************************取得队首元素*****************************************/
template<class NodeEntry>
void Queue<NodeEntry>::Retrieve(NodeEntry &item) const
{
item=Front->Entry;
}
/*******************************队列现有元素个数***************************************/
template<class NodeEntry>
int Queue<NodeEntry>::Size()const
{
return iCount;
}
/*******************************队列清空***********************************************/
template<class NodeEntry>
void Queue<NodeEntry>::Clear()
{
Node<NodeEntry> *pNode;
while(iCount>0)
{
pNode=Front;
Front=Front->Next;
delete pNode;
iCount--;
}
Front=Rear=NULL;
}