在写这篇文章之前,xxx已经写过了几篇关于改要求终点主题的文章,想要了解的朋友可以去翻一下之前的文章
虽然是看完LCY老师的课件之后再按照其思绪敲的
期间还错了几回,⊙﹏⊙b汗
先看下LCY老师说的奇偶性剪枝
再看这段代码
tem = t-cnt - s1 - s2;
其中t-cnt味残余的步数或者说时光,另其为T
s1+s2为残余步数,另其为S
如果走偶数步要求的时光是奇数,或者走奇数步要求的时光是偶数,都明显不可行
而轻易得出奇数-偶数 = 奇数,反之亦然
而奇数-奇数= 偶数,偶数-偶数=偶数
搜易tem必须为偶
理解了这里就没什么难的了
代码如下:
#include <stdio.h> #include <string.h> #include <math.h> int n,m,t; char map[10][10]; int flag; int di,dj,wall; int to[4][2] = {{0,-1},{0,1},{-1,0},{1,0}}; void dfs(int si,int sj,int cnt)//广搜 { int i,tem; if(si>n || sj>m || si<=0 || sj <= 0)//出界 return ; if(cnt == t && si == di && sj == dj)//到达终点 flag = 1; if(flag) return ; int s1 = si-di; int s2 = sj-dj; if(s1<0) s1=-s1; if(s2<0) s2=-s2; tem = t-cnt - s1 - s2; if(tem<0 || tem&1)//看剩下的时光能是不是到达终点,tem&1则是判断其是不是偶数,根据LCY的奇偶性剪枝可得tem必须是偶数,是奇数则不行 return; for(i = 0; i<4; i++) { if(map[si+to[i][0]][sj+to[i][1]]!='X') { map[si+to[i][0]][sj+to[i][1]]='X';//走过的地方变成墙 dfs(si+to[i][0],sj+to[i][1],cnt+1); map[si+to[i][0]][sj+to[i][1]]='.';//迷宫还原,以便下次广搜 } } return ; } int main() { int i,j,si,sj; while(~scanf("%d%d%d%*c",&n,&m,&t)) { if(!n && !m && !t) break; wall = 0; for(i = 1; i<=n; i++) { for(j = 1; j<=m; j++) { scanf("%c",&map[i][j]); if(map[i][j] == 'S') { si = i; sj = j; } else if(map[i][j] == 'D') { di = i; dj = j; } else if(map[i][j] == 'X') wall++; } getchar(); } if(n*m-wall<=t)//t是代表要走的步数,步数加墙数必须小于总格子数的,因为所有格子中还包括了S和D,这是剪枝 { printf("NO\n"); continue; } flag = 0; map[si][sj] = 'X';//起点是不可能再走的了,变成墙 dfs(si,sj,0); if(flag) printf("YES\n"); else printf("NO\n"); } return 0; }
文章结束给大家分享下程序员的一些笑话语录: 某程序员对书法十分感兴趣,退休后决定在这方面有所建树。花重金购买了上等的文房四宝。一日突生雅兴,一番磨墨拟纸,并点上了上好的檀香,颇有王羲之风 范,又具颜真卿气势,定神片刻,泼墨挥毫,郑重地写下一行字:hello world.
--------------------------------- 原创文章 By 要求和终点 ---------------------------------