数学家旅游

Description

有一个城市的道路由规则的方砖组成。有一位数学家来参观,他可沿方砖的边沿行走,有四种方法:n(0,1),s(0,-1),e(1,0),w(-1,0),但他是一个很怪的数学家,他会走一段时间休息一会儿,然后继续走。他有几个很特别的特性:
(1)不喜欢休息后走的方向和休息前的一样;
(2)第一次休息前走一步,休息后走的距离比休息前走的距离长一步;
(3)不喜欢重复走同一个地方;
(4)要走回出发点。
我们称他的路线是一个golygon。我们可以将出发的地点标记为(0,0),城市有几个地点正在施工,是不可以通行的。为了这位奇怪的科学家可以旅游得开心,我们决定帮他设计旅游的方案,找出城市中有多少个他希望的golygon。

Input

输入数据的第一行是golygons最大边的大小(不大于20),第二行是施工地点的个数(不大于50),以下的每一行有两个数字,表示施工的地点的坐标。

Output

输出每一个golygon的走法,每个占一行,最后输出golygon的个数。形式如输出样例。

Sample Input

8
2
-2 0
6 -2

Sample Output

wsenenws
Found 1 golygon(s).

Source

#include
#include
#include
#include
using namespace std;
int x[]={0,0,1,-1};
int y[]={1,-1,0,0};
int visited[21][21];

class move
{
public:
int dx,dy;
move(int x,int y)
{
dx=x;dy=y;
}
bool operator<(const move t) const
{
if(t.dx>dx && t.dy>dy)
return true;
}
bool operator==(const move t)const
{
if(t.dx==dx && t.dy==dy)
return true;
return false;
}
bool operator!=(const move t)const
{
if(t.dx==dx && t.dy==dy)
return false;
return true;
}
};
move src(10,10);
map direction;
vector > all;
void init()
{
//方向标识
direction[move(x[0],y[0])]='n';
direction[move(x[1],y[1])]='s';
direction[move(x[2],y[2])]='e';
direction[move(x[3],y[3])]='w';
for(map::iterator it =direction.begin(); it != direction.end(); ++it)
{
cout<second;
}

//边界设定
//第0行,0列,20行,20列为此次边界,不可访问
for(int i=0;i<21;i++)
{
visited[0][i]=-1;
visited[i][0]=-1;
visited[i][20]=-1;
visited[20][i]=-1;
}
}
namespace std
{
ostream& operator<<(ostream& os,move t)
{
// os< os<<"("< }
}
//第一次移动不可能回到起点,所以结构上是直接循环,否则就要先决断了
//count为步长
void search(vector& path,int a,int b,int max_lenth,int count,int change,int step,move last_move)
{
if(count>max_lenth) return;
int px,py,flag=0,pa=change,pb=step;
//每一次休息,下一个方向不能与休息前方向相同
if(count==change)
{
pa=count+step;
pb=step+1;
flag=1;
}
for(int i=0;i<4;i++)
{
move tmp(x[i],y[i]);
if(flag && tmp==last_move) //刚休息了,所以下个方向不能与前一个相同
{
// cout<<"变化的点:("< continue;
}
px=a+x[i];py=b+y[i]; //下面减枝
//不经过同一个点1,施工地点不经过-1,到达边界-1,反正都不为0
if(!visited[px][py])
{
cout<<"i="< path.push_back(tmp);
visited[px][py]=1;

search(path,px,py,max_lenth,count+1,pa,pb,tmp);

//恢复现场
visited[px][py]=0;
path.pop_back();
}else if(px==10 && py ==10){ //回到出发点等价于最后一点和起始点重合
path.push_back(tmp);
all.push_back(path);
cout<<"解决方案为:"< copy(path.begin(),path.end(),ostream_iterator(cout," "));
cout< path.pop_back();
}
}
}
main()
{
init();
visited[8][10]=-1; //施工,不可访问
visited[16][8]=-1; //施工坐标
vector path;
visited[10][10]=1;
search(path,10,10,8,0,1,2,move(2,2)); //8为最大长度
}

你可能感兴趣的:(算法)