题意:
一个人从(0,0)开始,每次走的长度是1,2,3...,每次走完一段,就必须向左或向右转,停留的点不能重复,并且不能经过障碍物;
现在给出最后一步走多远,以及障碍物的位置,求最后又走回(0,0)点的方法有几种,输出每种走法,还有走法总数;
思路:
暴力dfs();因为坐标有负数,所以我们把所有坐标+105,确保变正数;
还有一个剪枝就是,当现在的距离已经不可能回得去了,就结束;
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAX = 250; const int limit = 105; const int N = 50; int dir[4][2] = {{1,0},{0,1},{0,-1},{-1,0}}; char face[4] = {'e','n','s','w'}; int step[N],ans,n,m; int sum[25]; int g[MAX][MAX]; bool judge(int x,int y, int d,int f) { for(int i = 1; i <= d; i++) { x += dir[f][0]; y += dir[f][1]; if(abs(x) > limit || abs(y) > limit) return true; if(g[x + limit][y + limit] == -1) return true; } if(abs(x) + abs(y) > sum[n] - sum[d]) return true; return false; } void dfs(int x, int y, int d, int f) { if(d > n) { if(x == 0 && y == 0) { for(int i = 1; i <=n; i++) { printf("%c",face[step[i]]); } printf("\n"); ans++; } return; } for(int i = 0; i < 4; i++) { if(i == f || i + f == 3) continue; int xx = x + dir[i][0] * d; int yy = y + dir[i][1] * d; if(judge(x,y,d,i)) continue; if(g[xx + limit][yy + limit]) continue; g[xx + limit][yy + limit] = 1; step[d] = i; dfs(xx,yy,d + 1,i); g[xx + limit][yy + limit] = 0; } } int main() { sum[0] = 0; for(int i = 1; i <= 20; i++) { sum[i] = i + sum[i - 1]; } int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); memset(g, 0, sizeof(g)); ans = 0; int a,b; for(int i = 0; i < m; i++) { scanf("%d%d",&a,&b); if(abs(a) > limit || abs(b) > limit) continue; g[a + limit][b + limit] = -1; } dfs(0,0,1,-1); printf("Found %d golygon(s).\n\n",ans); } }
时间: 2024-11-07 14:57:48