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

考场一小时就速通交卷了,发个考场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-17 12:16
同济大学 Java
7182oat:快快放弃了然后发给我,然后让我也泡他七天最后再拒掉,狠狠羞辱他一把😋
点赞 评论 收藏
分享
Java抽象带篮子:难蚌,点进图片上面就是我的大头😆
点赞 评论 收藏
分享
评论
30
88
分享
牛客网
牛客企业服务