网易18实习生网测题--吃豆子
来源:互联网 发布:百度搜索软件 编辑:程序博客网 时间:2024/05/17 01:34
网易18实习生网测题–吃豆子
题目是酱滴,你是一个吃豆人,输入下面的参数,其中E表示没豆,W表示有豆。有三条规则:
4 5
EEWEW
EEWEE
EWEEE
EEEEW
- 初始化的时候你在左上角,面向右边,而且保证这里没有豆(意思是不存在一个图只有左上角有豆这样不需要动你就赢了嘛)
- 每一次你有两个移动选择,可以往面向的方向走一步
- 也可以往下面走一步,但这样你面向的方向要反过来
最后问你吃完所有豆子的最短路径。图的最大格数是150*150。
DFS法
我们敲代码,就是一把梭。这不是要问最短路吗,BFS写起来麻烦,后面还有两道题呢。那我赶紧写一个DFS试试。
void dfs(int pn, int pm, int dir, int steps, int now){ if(pn >=n || pm >= m) { return; } if(graphs[pn][pm] == 'W') now++; steps++; if(now >=target) { if(steps > answer) answer = steps; return; } if(dir ==0) { dfs(pn,pm-1,0,steps,now); dfs(pn+1,pm,1,steps,now); } else { dfs(pn,pm+1,1,steps,now); dfs(pn+1,pm,-1,steps,now); }}
每次历遍一次,要不往当前方向走一步,然后dfs,要不下走一步,转向,继续dfs。结束条件是出了边界,或者吃完所有豆子了。登登登,一提交,过了50%样例,后面的超时了……
这就很懵了。我当时也没想到好的剪枝的方法。也没考虑一下复杂度。之后我找到有人说
通常DFS和BFS复杂度大约均为:系数*状态数^层数
通常此数最多为1亿就八成爆掉
哦,意思是大概是2^150嘛……得,老老实实找规律。
O(n)的解法
看起来比较简单哈,其实有一个模拟的思想在里面的。根据题意我们可以知道,其实吃豆子是有规律的,每次都必须吃完这一行的才能往下走,而且往下走的时候,还必须满足能吃完下面一行的要求。所以我用pm指示当前豆子位于的列位置,历遍所有行。依据以下步骤:
1. 如果这一行没有豆子,我们就直接跳下一行
2. 先把指针指到能保证吃完这一行的位置(如果面向左边,指针要走到这一行的最右边的豆子那里;如果面向右边,就要走到最左边的豆子那里。),计算需要步数。
3. 吃完这一行(就是如果是面左,就走到最左的豆子那里;反之亦然),计算步数。
4. 走下一行,转方向,重复1
额外情况是,如果都没有豆子,输出0就可以了,根本不用走。这是40%和50%case test夹着的那个test case的情况。
看起来比较清晰的步骤,其实自己做起来不够熟练,所以一些细节都不够周全,拖了很久,要练要练啊。其实考虑清楚这个清晰的步骤之后,写起来就很快了。
#include <iostream>#include <cstdio>using namespace std;char graphs[150][150];int target;int n,m;int l[150];int r[150];int main(){ //freopen("1.in","r",stdin); target = 0; cin >> n >> m; for(int i = 0; i < n; i++) { l[i]=r[i]=-1; bool isl = true; for(int j = 0; j < m; j++) { cin >> graphs[i][j]; if(graphs[i][j] == 'W') { if(isl) { l[i]=j; isl=false; } r[i]=j; //cout<<l[i]<<r[i]<<endl; target++; } } } if(target == 0) { cout << 0 << endl; return 0; } int dire = 1; int ans = 0; int pm=0; bool flag =true; for(int i =0; i<n; i++) { if(l[i] < 0) { dire = -dire; continue; } if(flag) { ans += r[i]-pm; pm=r[i]; flag = false; dire = -dire; continue; } if(dire > 0) { if(pm > l[i]) { ans += pm - l[i] + r[i] - l[i]; pm=r[i]; } else { ans += r[i]-pm; pm=r[i]; } dire = -dire; } else { if(pm < r[i]) { ans += r[i]-pm + r[i]-l[i]; pm=l[i]; } else { ans += pm-l[i]; pm=l[i]; } dire = -dire; } } cout << ans+n-1 << endl; return 0;}
登登,这样就肯定能过了,毕竟输入的复杂度都是O(n*m)了,所以必须能过啊。
- 网易18实习生网测题--吃豆子
- 吃豆子
- google吃豆子游戏
- 吃豆子游戏
- 小游戏----吃豆子
- 吃豆子过桥问题
- 吃豆子过桥
- 吃豆子的小游戏
- CSS2D--吃豆子游戏
- c#吃豆子游戏,模仿百度在线应用吃豆子
- HTML5 canvas 模拟吃豆子
- c++实现吃豆子游戏
- 很怀旧的游戏--吃豆子
- 控制台界面的吃豆子游戏
- Java吃豆子游戏-2 接口
- 小游戏--吃豆子2 windows部分
- 手把手教学MFC吃豆子教程
- 一个简单的吃豆子游戏
- STL C++ Primer算法总结(一)
- java 多线程技术基础
- [BZOJ3307][雨天的尾巴][树链剖分+线段树]
- PHP获取访问者IP
- Java层到Native层Binder的流程
- 网易18实习生网测题--吃豆子
- ScrollView嵌套TextView文字上部截断下部有空隙
- 使用moy快速开发后台管理系统(四)
- BSI TR-03110
- JavaScript不懂的东西
- Java ClassLoader 类加载器
- #升级Android Studio2.3遇到的奇葩问题及最终解决方法
- 自考学习总结
- TensorFlow开源的三个原因