题意不说了,说的很清楚。
就是有一个细节!对于自交的理解!
书中说可以自交,意思是,可以首连接尾巴,每一个大点看作城市的话,不能重复经过城市,但能重复经过路线!
在一个麻烦之处在于坐标可以是负的,直接加上105就可以了!
可以理解为移动范围在0到105的正方形内!
为啥要加105呢,因为最多走20大步,20大步加起来就是210次,你一旦走出105的范围就在也回不去了!
因此最大步数是105步。
所以就可以有优化:
发现到目标点的距离大于 剩余可走的距离,直接return。
然后dfs即可!按字典序的话,直接方向按ensw遍历即可!
注意:
每一个输出后多一个空行!PE了一发~~
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100 + 5;
bool vis[2*maxn][2*maxn];
int mp[2*maxn][2*maxn];
const char dir[] = "ensw";
const int dx[] = {1,0,0,-1};
const int dy[] = {0,1,-1,0};
int n;
int a[25],ans;
char path[maxn];
void init(){
a[1] = 1;
for (int i = 2; i <= 25; ++i)
a[i] = i + a[i-1];
}
bool in(int x,int y){
if (x >= 2*maxn || y >= 2*maxn || x < 0 || y < 0)return false;
return true;
}
void dfs(int x,int y,int d,int step){
if (step >= n){
if (x != maxn || y != maxn)return;
path[step] = 0;
puts(path);
++ans;
return;
}
if (!in(x,y))return;
for (int i = 0; i < 4; ++i){
if (i ==d || i+d==3)continue;
bool ok = true;
int xx=x,yy=y;
for (int k = 0; k < step+1; ++k){
xx += dx[i];
yy += dy[i];
if (!in(xx,yy) || mp[xx][yy]){
ok=false;
break;
}
}
if (!ok || vis[xx][yy])continue;
vis[xx][yy]=1;
path[step] = dir[i];
dfs(xx,yy,i,step+1);
vis[xx][yy]=0;
}
}
int main(){
init();
int T;
scanf("%d",&T);
while(T--){
memset(mp,0,sizeof(mp));
memset(vis,0,sizeof(vis));
int k;
ans = 0;
scanf("%d%d",&n,&k);
while(k--){
int x,y;
scanf("%d%d",&x,&y);
x+= maxn;
y+= maxn;
mp[x][y] = 1;
}
dfs(maxn,maxn,100,0);
printf("Found %d golygon(s).\n\n",ans);
}
return 0;
}