题目大意:
从(0,0)出发往四个方向前进,每次前进1步,例如第一个一步(0,0)-》(0,1),第二次+1步就是(0,3),但是不能一直往同一个方向走和往回走,问你从起点到出发又回到起点了路径有多少条并输出来。
思路:
第一份代码:
因为坐标是负数,我用一个数组去映射,然后比较的时候一一遍历。
另外题目没说清楚,访问过一次了的点下次是不能再访问的。
还有不能穿越障碍物。
把这几个因素考虑到大概就是这份代码了,然后wa了一个中午(awsl),大概原因应该是出在check上面了,可能因素不全(尽管debug数据全过了)
#include<bits/stdc++.h>
using namespace std;
struct node{
int x,y;
};
const int maxn=1024;
const int dis=130;
int path[maxn];
node id[maxn];
int t,n,k,ans;
char dir[4]={'e','n','s','w'};
int vis[maxn][maxn];
bool check(int x,int y,int d){
for(int i=0;i<k;i++){
if(d==1){
if(y>=id[i].y&&id[i].x==x)return false;
}
if(d==2){
if(y<=id[i].y&&id[i].x==x)return false;
}
if(d==3){
if(x<=id[i].x&&id[i].y==y)return false;
}
if(d==0){
if(x>=id[i].x&&id[i].y==y)return false;
}
}
return true;
}
/*bool canwalk(int x,int y){ if(x==0||x==3){ return (y==2||y==1); } if(x==2||x==1){ return (y==0||y==3); } }*/
void dfs(int x,int y,int step,int d){
if(step>n){
if(x==0&&y==0){
ans++;
for(int i=1;i<=n;i++){
printf("%c",dir[path[i]]);
}
printf("\n");
}
return ;
}
for(int i=0;i<4;i++){
int fx=x,fy=y;
switch(i){
case 1:{fy+=step;break;}
case 2:{fy-=step;break;}
case 3:{fx-=step;break;}
case 0:{fx+=step;break;}
}
if (i == d || i + d == 3) continue;//学习,直接看规律
if(check(fx,fy,i)&&!vis[fx+dis][fy+dis]){
vis[fx+dis][fy+dis]=1;
path[step]=i;
dfs(fx,fy,step+1,i);
vis[fx+dis][fy+dis]=0;
}
}
}
int main(){
scanf("%d",&t);
while(t--){
int flag=0;
ans=0;
memset(vis,0,sizeof(vis));
scanf("%d%d",&n,&k);
int x,y;
for(int i=0;i<k;i++){
scanf("%d%d",&x,&y);
if(x==0&&y==0)flag=1;
id[i].x=x;
id[i].y=y;
vis[x+dis][y+dis]=1;
}
if(flag){
printf("Found 0 golygon(s).\n\n");
continue;
}
dfs(0,0,1,-1);
printf("Found %d golygon(s).\n\n",ans);
}
return 0;
}
然后参考了别人的代码,因为n最多为20,那么第三象限最小值不会超过(-110,-100),那么将所有坐标平移(x+120,y+120)就能直接用二维数组判断是否已经访问过,然后怎么判断是否穿过障碍,在数组vis[x][y]=-1表示(x,y)存在障碍,vis[x][y]=0(x,y)可以访问 。vis[x][y]=1表示(x,y)已经访问过了且不是障碍。
这份代码里面的check是模拟一步一步去穿过石头的,我的直接判断可以不够周全。。。。。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=250;
const int dis=105;
int path[maxn];
int t,n,k,ans;
char dir[4]={'e','n','s','w'};
int dx[]={1,0,0,-1};
int dy[]={0,1,-1,0};
int vis[maxn][maxn];
int sumSteps[25];
bool check(int x,int y,int i,int k){
for (int t = 1; t <= k; t++){//模拟穿越石头
int newx = x + dx[i]*t;
int newy = y + dy[i]*t;
if (abs(newx) > dis || abs(newy) > dis) return false;
if (vis[newx+dis][newy+dis] == -1) return false;
}
return true;
}
void dfs(int x,int y,int step,int d){
if(step>n){
if(x==0&&y==0){
ans++;
for(int i=1;i<=n;i++){
printf("%c",dir[path[i]]);
}
printf("\n");
}
return ;
}
for(int i=0;i<4;i++){
path[step]=i;
if (i == d || i + d == 3) continue;
if(!check(x,y,i,step))continue;
int newx=x+dx[i]*step;
int newy=y+dy[i]*step;
if(vis[newx+dis][newy+dis])continue;
vis[newx+dis][newy+dis]=1;
dfs(newx,newy,step+1,i);
vis[newx+dis][newy+dis]=0;
}
}
int main(){
scanf("%d",&t);
while(t--){
ans = 0;
scanf("%d%d",&n,&k);
memset(vis,0,sizeof(vis));
for (int i = 0; i < k; i++){
int a, b;
cin >> a >> b;
vis[a + dis][b + dis] = -1;//障碍用-1表示,访问过用1表示
}
dfs(0,0,1,-1);
printf("Found %d golygon(s).\n\n",ans);
}
return 0;
}