回 帖 发 新 帖 刷新版面

主题:一些有关递归回溯的程序

//
// road.cpp acm消防车题(91.A)
// lanjingquan     2002.7.20
///////////////////////////////////////////

#include"road.h"

ROAD::ROAD()
{
init();
times2=1;
record=new int[22];
}

bool ROAD::GetDataAndFind(char* file)
{
ifstream input(file,ios::nocreate);
int row,col;
while(!input.eof())
{
input>>goal;

input>>row>>col;
while(row!=0&&col!=0)
{
data[row][col]=1;
data[col][row]=1;
input>>row>>col;
}
FindRoad();
init();
}

return true;
}

bool ROAD::FindRoad(const int first,int& idx)
{
int n=idx;
record[n++]=first;

if(first==goal)
{
for(int j=0;j<idx;j++)
cout<<record[j]<<" ";
cout<<goal<<endl;
times++;
return true;
}

for(int i=1;i<=21;i++)
if(data[first][i]==1&&data[i][i]==0)
{
data[i][i]=1;
FindRoad(i,n);
data[i][i]=0;
}

return true;
}

bool ROAD::FindRoad()
{
cout<<"CASE# "<<(times2++)<<":"<<endl;
int i=0;
data[1][1]=1;
FindRoad(1,i);
cout<<"There are "<<times
<<" routes from the firestation to streetcorner "
<<goal<<"."<<endl<<endl;
return true;
}

bool ROAD::init()
{
for(int i=0;i<=21;i++)
for(int j=0;j<=21;j++)
data[i][j]=0;

goal=0;
times=0;

return true;
}

ROAD::~ROAD()
{
delete[] record;
}

回复列表 (共9个回复)

沙发

//
// test.cpp
// lanjingquan  2002.7.20
//////////////////////////////////////////////

#include"road.h"

void main()
{
ROAD road;
road.GetDataAndFind("data.txt");
}

板凳

//
// 八王问题
// lanjingquan  2002.4.8
////////////////////////////////////////////////

#include<iostream.h>

void Queen(int);
int col[8];
int md[15];
int sd[15];
int q[8];
int sum=0;

////////////////// main ///////////////////////
void main()
{
cout<<"______ 八王后问题 _____"<<endl;
Queen(0);
cout<<"sum: "<<sum<<endl;
}

////////////////// Queen //////////////////////
void Queen(int i)
{
for(int j=0;j<8;j++)
if(col[j]==0&&md[8+i-j-1]==0&&sd[i+j]==0)         //第 i 行第 j 列没有攻击
{  
col[j]=1;
md[8+i-j-1]=1;
sd[i+j]=1;
q[i]=j;                           //在第 i 行第 j 列安放皇后

if(i==7)
{
sum++;
for(int k=0;k<8;k++)                      //输出一个布局
cout<<q[k]<<",";
cout<<endl;
}

Queen (i+1);           //在第i+1行安放皇后

col[j]=md[8+i-j-1]=sd[i+j]=0;   //撤消第 i 行第 j 列攻击标志
q[i]=0;                                       //撤消第 i 行第 j 列的皇后,使回溯
}
}

3 楼

//
// 电子锁 lanjingquan  2002.4.12
// 不妨设总人数为man,且当持卡人数大于together时,电子锁可开,
// 数学分析可得,卡上最少所须特征数为C(man,man-together+1)
// 每个卡上所须特征数为C(man-1,together-1),故只须列出组合即可
//////////////////////////////////////////////////////////////////

#include<iostream.h>

int man=8;
int together=4;
static int total=0;
static int times=0;
int stack[5];
char way[9][57];

char ch(int); //产生信息码
void make(int,int); //产生卡中码

////////////////////// main /////////////////////////
void main()
{
cout<<"输出所有可能的组合:"<<endl;
make(0,0);

cout<<endl
<<"********************************************************* 卡中信息值 **********************************************************"<<endl;
for(int i=1;i<9;i++)
{
cout<<"第"<<i<<"张卡的信息:";
for(int j=1;j<57;j++)
cout<<way[i][j]<<",";

cout<<endl;
}
cout<<"*******************************************************************************************************************************"<<endl
<<"卡中特征信息总数:"<<times<<endl;
}

//////////////////// make //////////////////////////
void make(int l,int last)
{
if(l==5)
{
     for(int p=0;p<5;p++)
cout<<stack[p]<<"  ";
cout<<"           ";

total++;
times++;

for(int i=0;i<5;i++)
way[stack[i]][times]=ch(total);
}

for(int i=last+1;i<=man;i++)
{
stack[l]=i;
make(l+1,i);
}
}

////////////////////// ch //////////////////////////
char ch(int total)
{
return total+20;
}



4 楼

//
// findOK.cpp lanjingquan  2002.3.29
// 有n个数,其入栈顺序为1.2.3.4......n,找出所有可能
// 的出栈序列和不可能序列,打印出来结果,并统计总数
/////////////////////////////////////////////////////////

#include<iostream.h>
#include<afxcoll.h>

void Find(CUIntArray&,CUIntArray&);
bool testArray(CUIntArray&);
long int factorial(int);
bool testPart(int*);
void print(CUIntArray&);
long sum=0;

////////////////// main /////////////////////////////////
void main()
{
long n;
do{
cout<<"请输入待排元素总数(N>2):"<<endl;
cin>>n;
if(n<3)
cout<<"输入有误,请重新输入..."<<endl;
}while(n<3);

cout<<"计算中,请稍候......"<<endl;
CUIntArray a;
CUIntArray b;
a.SetSize(0);
b.SetSize(n);
for(int i=1;i<=n;i++)
b.SetAt(i-1,i);

Find(a,b);
cout<<"所有的不可能出栈序列如上所示,共有 "<<sum<<" 种。"<<endl
<<"所有可能出栈序列有 "<<factorial(n)-sum<<" 种。"<<endl;
}

////////////////// find /////////////////////////////////
void Find(CUIntArray& pa,CUIntArray& pb)
{
if(pb.GetSize()==0)
testArray(pa);
else
for(int i=0;i<pb.GetSize();i++)
{
CUIntArray c;
CUIntArray d;
c.Copy(pa);
d.Copy(pb);

c.Add(d[i]);
d.RemoveAt(i);

Find(c,d);
}
}       

//////////////// testArray //////////////////////////////
bool testArray(CUIntArray& pa)
{
int i=0;
while(i<pa.GetSize())
{
int test0[3]={0,0,0};
test0[0]=pa.GetAt(i);
for(int a=i;a<pa.GetSize();a++)
{
test0[1]=pa.GetAt(a);
for(int b=a;b<pa.GetSize();b++)                               
{
test0[2]=pa.GetAt(b);
if(!testPart(test0))
{
sum++;
print(pa);
return 0;
}
}
}
i++;
}
return 1;
}

//////////////////// factorial ////////////////////////
long int factorial(int n)
{
if(n==0) return 1;
else return n*factorial(n-1);
}

/////////////////// testpart ///////////////////////////
bool testPart(int* test)
{
if(test[2]>test[1]&&test[2]<test[0])
return 0;
else
return 1;
}

////////////////// print ///////////////////////////////
void print(CUIntArray& a)
{
for(int i=0;i<a.GetSize();i++)
cout<<a[i]<<"  ";
cout<<endl;
}

5 楼

//
// maze.cpp
// lanjingquan  2002.5.11
////////////////////////////////////////////////////

#include<iostream.h>
#include"stack.h"

struct items
{
int x;
int y;
int dir;//方向


};

ostream& operator<<(ostream& os,items& item)//输出函数
{
return os<<item.x<<","<<item.y<<","<<item.dir;
}

struct offset
{
int a; //x方向偏移
int b;  //y方向偏移
};

enum directions{N,NE,E,SE,S,SW,W,NW};//方向
offset move[8]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};//移动方向表

int maze[12][9]={{1,1,1,1,1,1,1,1,1},
{1,0,0,1,1,1,1,1,1},
{1,1,0,1,1,1,0,1,1},
{1,1,1,0,1,1,1,1,1},
{1,1,1,1,0,1,1,1,1},
{1,1,1,0,1,0,1,1,1},
{1,1,0,1,1,1,0,1,1},
{1,1,0,1,1,1,0,1,1},
{1,1,0,1,1,1,0,1,1},
{1,1,0,1,1,1,0,1,1},
{1,1,1,1,1,1,1,0,1},
{1,1,1,1,1,1,1,1,1}};
int mark[12][9]={0};         //记录数组

void path(int m,int p)
{
mark[1][1]=1; //入口
STACK<items> st; //记录栈

items tmp;//初始化
tmp.x=1;
tmp.y=1;
tmp.dir=E;

st.push(tmp);//进栈
while(!st.isEmpty())//非空,持续下去
{
tmp=st.pop();//退栈
int i=tmp.x;
int j=tmp.y;
int d=tmp.dir;//偏移表下标

while(d<8)//还有移动,继续移动
{
int g=i+move[d].a;//下一位置
int h=j+move[d].b;
if(g==m&&h==p)//出口
{
cout<<st;//输出
cout<<i<<"  "<<j<<endl;
cout<<m<<"  "<<p<<endl;
return;
}
if(!maze[g][h]&&!mark[g][h])//末到出口,下一位置
{
mark[g][h]=1;//标记为访问过
tmp.x=i;
tmp.y=j;
tmp.dir=d+1;
st.push(tmp);//进栈
i=g;//移动
j=h;
d=N;
}
else d++;//尝试下一方向
}
}
cout<<"no path in maze!"<<endl;
}

void main()
{
path(10,7);
}

6 楼

顶一下,不错,收集!

7 楼

厉害,可以问一下你编过的最长的程序有多长吗?

8 楼

[em5][em5][em5][em5]

9 楼

给一下stack.h的代码行吗?

我来回复

您尚未登录,请登录后再回复。点此登录或注册