网易2021暑期实习 游戏开发 笔试

昨晚参加的网易的这次笔试,是我做过所有应聘笔试里最容易的。两个半小时,才3道题,难度较高的只有一题。

题1:printf中的if

小易刚学C语言,学了if和printf,他想自己写一个printf函数。于是他写出了如下的代码:

void myPrintf(char* format){
	bool token_flag = 0;
	while(true){
		if(*format == '\0'){
			/* Handle */
			return;
		}
		else if(token_flag){
			if(*format == 's'){
				/* ... */
				token_flag = 0;
			}
			else if(*format == 'd'){
				/* ... */
				token_flag = 0;
			}
			else if(*format == 'u'){
				/* ... */
				token_flag = 0;
			}
			else if(*format == 'p'){
				/* ... */
				token_flag = 0;
			}
			else if(*format == 'f'){
				/* ... */
				token_flag = 0;
			}
			else if(*format >= '1' && *format <= '9'){
				/* ... */
			}
			else if(*format == '%'){
				/* ... */
				token_flag = 0;
			}
			else{
				/* ... */
				token_flag = 0;
			}
		}
		else{
			if(*format == '%'){
				/* ... */
				token_flag = 1;
			}
			else{
				/* ... */
			}
		}
		format++;
	}
	return;
}

小易不会swtich,只好用很多if else。他想知道,对于给定的语句,myPrintf函数会进行多少次if判断(else不算)。
例如,对于%2d,会进行16次if判断。

这题乍一看我头都大了。给了这么长的代码(结构是这样,注释等处不一样),不知道有什么用,而且字符串处理是我的弱项。
仔细观察,发现其实很简单。分析可知,由于每一个字符的判断次数只和它自己以及token_flag的值有关,每个字符至多只有两种情况,那只要把字符串从前到后扫描一遍就能得出结果。
我画了一个表:

t_f\0sdupfdigit%other
01333333.33
11.3.4..5.6.78.9.9

t_f表示token_flag,第3行第3列就表示扫描到s时会增加3次if判断次数,小数点表示会改变token_flag的值。
然后扫描就行了。甚至不需要用c/cpp,用Java即可。

题2:乒乓球比赛

公司里有两个部门A和B要举办乒乓球比赛。每个部门出3名男选手、3名女选手,举行男双一场、女双一场、混双一场,每人只能参加一场比赛。
部门B的小亮想知道,自己的部门有多大可能赢。为此,他给双方共计12名球手做了分析,给每个人都打了一个战力分数。他认为,一场比赛中,两个选手的战力分数加起来高的那一方会获胜,如果一样高则A部门获胜。
他希望知道,一共有多少种阵容能使得部门B获胜。定义两个阵容是不同的,当且仅当其中至少有一场比赛有一方派出了不同的选手。

乍一看又很难。仔细一想,其实每个部门只有9种阵容,因为关键在于派哪个男哪个女去参加混双,一共只有3*3种选择。
假设1、2、3为男选手,4、5、6为女选手,数组cast[6]是1~6的一个排列,前两个选手参加男双,中间两个参加混双,后面两个参加女双,那么一个部门的所有阵容都可以用cast来表示,而cast只有能形成以下九种不同的阵容:

1 2 3 4 5 6
1 3 2 4 5 6
2 3 1 4 5 6
1 2 3 5 4 6
1 3 2 5 4 6
2 3 1 5 4 6
1 2 3 6 4 5
1 3 2 6 4 5
2 3 1 6 4 5

两边一共也就81种。那我全算一遍是不是就可以了……我就写了个这么暴力遍历的算法,结果就过了。
这数据还是太宽松了(窃喜)。

题3:迷宫最短路径

有一个迷宫,里面一片漆黑,不知道哪里能走、哪里不能。
但我们现在已经有了一条从起点走到终点的记录。这个记录走了很多步,有时会发现一个方向走不通,则停在原地;有时能走通,则移动位置。
现在希望根据这条记录,找出从起点到终点的最短路径的长度。请注意,如果一个位置没有被探索过,则认为是走不通的。
输入格式:
第一行是数据组数。每组数据对应一个迷宫,其第一行是路径记录的步数n( n ⩽ 1 , 000 , 000 n \leqslant 1,000,000 n1,000,000),接下来n行每一行表示一步。一步由两个整数组成,第一个整数是{0, 1, 2, 3}之一,分别表示向上、向下、向左、向右;第二个整数是{1, -1}之一,分别表示能走通、走不通。
输出格式:
对于每组数据,输出从起点到终点的最短路径的长度。

一个很朴素的思路是,画一个巨大的地图,根据路径记录把所有能到达的地方都标出来,其他地方标为不可到达,然后广搜。
这样引出两个问题:

  1. 起点应该放在哪里。由于起点位置是没有给出的,后面的方向在建立地图时也是位置的,所以难以确定把起点放在哪里。最万全的方案当然是放在正中间,但那又引出第二个问题。
  2. 内存不够使用。即使问题1不存在,已经确定起点在迷宫左上角,由于步数的上限是一百万,为了覆盖诸如“连续往右走一百万步”的极端情况,不得不把数组开为map[1000000][1000000],内存空间严重不足。那如果考虑问题1,数组又得变为原来的四倍大小,更不可能。实际上给c/cpp的空间就只有65536KB(具体数字可能不对,但肯定是万KB的数量级),给Java的也只是大概两倍而已。

我只开了个100*100的数组,想着能过一点case是一点。然而由于我脑子抽了,不用广搜用了深搜,不断地超时,过了0.00%的case。
暂时不知道怎么做。

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值