搜索水题四连发_C++
特别声明:以下题目有部分为原创题,涉及版权问题,不得转载,违者追究 法律责任!
话说这是一套神题,只有你想不到,没有你做不到
题目更正后比 Pascal 跑得还快哈~
一道特别裸,但是特别坑的搜索题
题解给出了一行字
这个包含的意思就很多了~比如DFS的深度是第几朵花,而不是位置
然后搜索要从 n 开始,反过来搜
枚举位置的时候,加上一个 f 数组判重即可
没有任何剪枝,但如果你是从 1 开始你就能拿到 10 分的高分,TLE 9个点
证明我也不会,题解没讲,百度也没有
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 using namespace std; 8 9 char s[41][10]; 10 int f[81],n; 11 void dfs(int x) 12 { 13 int i; 14 if (!x) 15 { 16 for (i=1;i<=n;i++) puts(s[f[i]]); 17 exit(0); 18 } 19 for (i=1;i<=n-x-1;i++) 20 { 21 if (f[i]||f[i+x+1]) continue; 22 f[i]=x; 23 f[i+x+1]=x; 24 dfs(x-1); 25 f[i]=0; 26 f[i+x+1]=0; 27 } 28 } 29 int main() 30 { 31 freopen("flower.in","r",stdin); 32 freopen("flower.out","w",stdout); 33 int i; 34 scanf("%d\n",&n); 35 for (i=1;i<=n;i++) gets(s[i]); 36 n*=2; 37 dfs(n/2); 38 return 0; 39 }
一开始我还想成了DP题,以为只要往下和右转移就行,结果发现如果有墙而需要往上面或者左边绕的时候会得到0
后面回头看一眼数据范围12,显然DFS
不剪枝,每次向四周走,判断有没有墙和有没有超界,然后走过的地方要打标机,30 分
加第一个剪枝,如果当前已走步数大于答案,则不会再更行到答案,直接return,80分
加第二个剪枝,如果目标地点与当前地点之间最近的路线(不考虑墙,也就是abs(x-x_now)+abs(y-y_now)>ans)大于答案,也可以return,90分
加第三个剪枝(强行优化),先往右边走再往下边走,100分
最后一个剪枝就是这套题最坑的地方2333333
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 using namespace std; 8 9 const int N=13; 10 int n,m,mx,my,ans=2000000000,tot; 11 bool g[N][N],f[N][N]; 12 void dfs(int x,int y,int dep) 13 { 14 if (x==mx&&y==my) 15 { 16 if (dep<ans) 17 { 18 ans=dep; 19 tot=1; 20 } 21 else if (dep==ans) tot++; 22 return; 23 } 24 if (dep==ans||abs(mx-x)+dep>ans||abs(my-y)+dep>ans) return; 25 f[x][y]=1; 26 if (y+1<=m&&f[x][y+1]==0&&g[x][y+1]) dfs(x,y+1,dep+1); 27 if (x+1<=n&&f[x+1][y]==0&&g[x+1][y]) dfs(x+1,y,dep+1); 28 if (x-1>0&&f[x-1][y]==0&&g[x-1][y]) dfs(x-1,y,dep+1); 29 if (y-1>0&&f[x][y-1]==0&&g[x][y-1]) dfs(x,y-1,dep+1); 30 f[x][y]=0; 31 } 32 int main() 33 { 34 freopen("maze.in","r",stdin); 35 freopen("maze.out","w",stdout); 36 int i,j,c; 37 scanf("%d%d%d%d",&n,&m,&mx,&my); 38 for (i=1;i<=n;i++) 39 for (j=1;j<=m;j++) 40 { 41 scanf("%d",&c); 42 if (c==0) g[i][j]=1; 43 } 44 dfs(1,1,1); 45 printf("%d\n",tot); 46 return 0; 47 }
第三题是原题,我以前写过题解,具体请戳
http://www.cnblogs.com/hadilo/p/5746894.html
第四题是NOIP2003的第四题,我也写过题解
http://www.cnblogs.com/hadilo/p/5916654.html
就这么水过了,很森破啊~