米哈游笔试题目思路(客户端卷)

考场一小时就速通交卷了,发个考场AC代码。肯定还能优化,轻喷。代码一题比一题短。。。

1.矩阵连通块

思路两次dfs,一次是正常的,一次是按照B和G等价来看。

#include<iostream>

using namespace std;

int n, m;
string s[1010];
bool vis1[1010][1010], vis2[1010][1010];
const int mv[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};

int dfs1(int x, int y) {
	if(x < 0 || x >= n) return 0;
	if(y < 0 || y >= m) return 0;
	if(vis1[x][y]) return 0;
	if(!vis1[x][y]) vis1[x][y] = true;
	for(int i = 0; i < 4; i++) {
		if(x + mv[i][0] < 0 || x + mv[i][0] >= n) continue;
		if(y + mv[i][1] < 0 || y + mv[i][1] >= m) continue;
		if(s[x + mv[i][0]][y + mv[i][1]] == s[x][y])
			dfs1(x + mv[i][0], y + mv[i][1]);
	}
	return 1;
}
int dfs2(int x, int y) {
	if(x < 0 || x >= n) return 0;
	if(y < 0 || y >= m) return 0;
	if(vis2[x][y]) return 0;
	if(!vis2[x][y]) vis2[x][y] = true;
	for(int i = 0; i < 4; i++) {
		if(x + mv[i][0] < 0 || x + mv[i][0] >= n) continue;
		if(y + mv[i][1] < 0 || y + mv[i][1] >= m) continue;
		if(s[x][y] == 'G' || s[x][y] == 'B') {
			if(s[x + mv[i][0]][y + mv[i][1]] == 'G' || s[x + mv[i][0]][y + mv[i][1]] == 'B')
				dfs2(x + mv[i][0], y + mv[i][1]);
		}
		else if(s[x + mv[i][0]][y + mv[i][1]] == s[x][y])
			dfs2(x + mv[i][0], y + mv[i][1]);
	}
	return 1;
}
int main() {
	cin >> n >> m;
	for(int i = 0; i < n; i++) {
		cin >> s[i];
	}
	int cnt = 0;
	for(int i = 0; i < n; i++) {
		for(int j = 0; j < m; j++) {
			cnt += dfs1(i, j);
		}
	}
	
	for(int i = 0; i < n; i++) {
		for(int j = 0; j < m; j++) {
			cnt -= dfs2(i, j);
		}
	}
	
	cout << cnt;
	return 0;
}

2.mhy字符串

手动玩一下可以发现mhy这三个字的顺序没有任何关系。

例如:yhm->mhyhmy->mhyhmy->hym

然后hym通过类似的操作就可以变成mhy,因此这个插入删除就等价于无序插入删除而且可以随意调整已有的顺序。

然后只需要比较mhy之外的字符串是否相等,已经mhy三个字符之间的数量关系。

#include <bits/stdc++.h>

using namespace std;

int bin_s[3], bin_t[3];

int main() {
	int T;
	cin >> T; 
	while(T--) {
		bin_s[0] = bin_s[1] = bin_s[2] = 0;
		bin_t[0] = bin_t[1] = bin_t[2] = 0;
		string s, t;
		cin >> s >> t;
		string new_s, new_t;
		for(int i = 0; i < (int) s.length(); i++) {
			if(s[i] == 'm') bin_s[0]++;
			else if(s[i] == 'h') bin_s[1]++;
			else if(s[i] == 'y') bin_s[2]++;
			else new_s.push_back(s[i]);
		}
		for(int i = 0; i < (int) t.length(); i++) {
			if(t[i] == 'm') bin_t[0]++;
			else if(t[i] == 'h') bin_t[1]++;
			else if(t[i] == 'y') bin_t[2]++;
			else new_t.push_back(t[i]);
		}
		if(new_s == new_t) {
			if(bin_s[0] - bin_t[0] == bin_s[1] - bin_t[1] 
			&& bin_s[0] - bin_t[0] == bin_s[2] - bin_t[2])
				cout << "Yes" << endl;
			else cout << "No" << endl;
		}
		else cout << "No" << endl;
	}
	return 0;
}

3.子集合计数

简单O(nsqrt(a))的dp,排序之后dp[i]代表以a[i]结尾的数的集合数量。那么dp[i]只需要从所有a[i]的因数处转移,因为集合不可重复,所以可以排序之后令pos[a[i]] = i,没有的就-1,所以sqrt(a[i])枚举一下因数,用pos桶查坐标,都加上就行。

#include <bits/stdc++.h>

using namespace std;

const long long M = 1000000007;
int a[100010], pos[1000010];
int dp[100010];

int main() {
	memset(pos, -1, sizeof(pos));
	int n;
	scanf("%d", &n);
	for(int i = 0; i < n; i++) {
		scanf("%d", &a[i]);
	}
	sort(a, a + n);
	for(int i = 0; i < n; i++) {
		pos[a[i]] = i;
	}
	long long ans = 0;
	for(int i = 0; i < n; i++) {
		int tmp = a[i];
		for(int j = 1; j * j <= tmp; j++) {
			if(tmp % j == 0) {
				if(pos[tmp / j] > -1 && j != tmp / j) {
					dp[i] += dp[pos[tmp / j]];
				}
				if(pos[j] > -1) {
					dp[i] += dp[pos[j]];
				}
			}
		}
		ans += dp[i];
		ans %= M;
		dp[i]++;
	}
	cout << ans;
	return 0;
}

#米哈游##米哈游2023春招求职进度交流#
全部评论
大佬我咋没看懂你的这个例子表达的意思,例如:yhm->mhyhmy->mhyhmy->hym,能细说一下嘛
2 回复 分享
发布于 2023-03-20 10:19 北京
大佬太强了,搞不定搞不定,我已经和米哈游无缘了😹
1 回复 分享
发布于 2023-03-20 07:40 美国
第三题我理解错了,我以为求等比数列的个数,怎么都没写出来,睡前突然想明白题目不是指等比数列
点赞 回复 分享
发布于 2023-03-20 10:48 陕西
第三题复杂度不对
点赞 回复 分享
发布于 2023-03-20 11:31 浙江
tql
点赞 回复 分享
发布于 2023-03-20 11:58 上海
为什么我也是客户端结果和你一道题也不一样,每道都好难的那种
点赞 回复 分享
发布于 2023-03-20 13:50 浙江
大佬,求问为什么需要dp[i]++呀, ans += dp[i]; ans %= M; dp[i]++;
点赞 回复 分享
发布于 2023-04-13 10:45 广东

相关推荐

10-07 23:57
已编辑
电子科技大学 Java
八街九陌:博士?客户端?开发?啊?
点赞 评论 收藏
分享
鼗:四级有点难绷,感觉能拿国家励志奖学金,学习能力应该蛮强的,四级确实不重要,但是拿这个卡你可是很恶心啊
点赞 评论 收藏
分享
30 88 评论
分享
牛客网
牛客企业服务