牛客小白月赛49

A

在这里插入图片描述

签到

读取字符串之后,按位转化成数字,%3输出

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include<unordered_map>
#include <unordered_set>

using namespace std;

typedef long long ll;
const int N = 1e4 + 5;
const int MOD = 1e9 + 7;

char s[3], t[3];
int main() {
	scanf("%s %s", s, t);
	int a = s[0] - '0' + t[0] - '0';
	a %= 3;
	int b = s[1] - '0' + t[1] - '0';
	b %= 3;
	int c = s[2] - '0' + t[2] - '0';
	c %= 3;
	printf("%d%d%d", a, b, c);
	return 0;
}

B

在这里插入图片描述
在这里插入图片描述

模拟

现在看,感觉写麻烦了
用 s 数组存收到的礼物和对应颜色(写繁了,导致后面是直接搜,浪费时间,应该直接赋值的,这样查找就是O(1))
然后没输入一个颜色,就判断一次
因为颜色判断是累加的,意思就是咱们最后输入的是 3 2 1 ,判断第一个 3 时,找有三的礼物就行,判断第二个 2 的时候,要统计 同时 有颜色 3 和 2 的礼物
如果一个礼物在某一次颜色判断中,不满足条件,就把这个礼物的颜色的第一个 赋值为1,遍历的时候判断跳过即可

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include<unordered_map>
#include <unordered_set>

using namespace std;

typedef long long ll;
const int N = 205;
const int MOD = 1e9 + 7;

int n, m;
int s[N][N];

void solve() {
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &s[i][j]);
		}
	}

	int a, cnt = 0;
	for (int i = 0; i < m; i++) {
		scanf("%d", &a);
		for (int j = 0; j < n; j++) {
			bool flag = false;
			for (int k = 0; k < m; k++) {
				if (s[j][0] == -1) break;
				if (s[j][k] == a) {
					cnt++, flag = true;
					break;
				}
			}
			if (flag == false) s[j][0] = -1;
		}
		printf("%d ", cnt);
		cnt = 0;
	}
	
	printf("\n");
}

int main() {
	int T;
	scanf("%d", &T);
	while (T--)
		solve();
	return 0;
}

桶排

vis[],第 i 件物品,含有颜色…,这个是直接赋值,O(1) 查找
judge[] 是第 i 个礼物目前是否还满足条件
b[] 接收要查找的颜色

先遍历颜色,内层遍历礼物,逐个礼物的判断,如果b数组的颜色,这个礼物有,并且还满足条件,就ans++
否则judge = 1,表示不满足条件了,一种颜色遍历完之后输出即可

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include<unordered_map>
#include <unordered_set>

using namespace std;

typedef long long ll;
const int N = 205;
const ll MOD = 1e9 + 7;

int n, m, a;
int vis[N][N]; // 第 i 件 物品 含 颜色 j
int judge[N]; // 第 i 件 物品 是否还满足条件
int b[N];

void solve() {
	memset(vis, 0, sizeof(vis));
	memset(judge, 0, sizeof(judge));
	memset(b, 0, sizeof(b));
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++) {
			scanf("%d", &a);
			vis[i][a] = 1; // 第 i 件物品,有颜色a
		}
		
	for (int i = 0; i < m; i++) scanf("%d", &b[i]);
	
	for (int j = 0; j < m; j++) {
		int ans = 0;
		for (int i = 0; i < n; i++) {
			if (vis[i][b[j]]) {
				if (!judge[i]) ans++;
			}
			else {
				judge[i] = 1;
			}
		}
		printf("%d%c", ans, (j == m - 1) ? '\n' : ' ');
	}

}

int main() {
	int T;
	scanf("%d", &T);
	while (T--)
		solve();
	return 0;
}

C

在这里插入图片描述
在这里插入图片描述

位运算 + 思维

ai & aj ,& 只有两个对应位置 是 1 时才是 1,所以,& 操作只能是原有的1数量不变,或者减少,不可能增加,所以& 之后的值一定是小于等于 ai 和 aj 的,而且是小于他们其中小的那个
又有,| 运算,其实是在 加 1 的操作,因为一定有一项是 ai & ai 的,结果是 ai,其他的所有 & 值,一定是小于等于 ai 的,所有 ai | 其他的值,结果就是 ai
所以 最后的结果其实就是 把 a1~an 所有的值 异或起来
在这里插入图片描述

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include<unordered_map>
#include <unordered_set>

using namespace std;

typedef long long ll;
const int N = 5e5 + 5;
const int MOD = 1e9 + 7;

int n, a[N];
long long res = 0;
void solve() {
	scanf("%d", &n);
	res = 0;
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
		res ^= a[i];
	}
	printf("%lld\n", res);
}

int main() {
	int T;
	scanf("%d", &T);
	while (T--)
		solve();
	return 0;
}

D

在这里插入图片描述

二次函数图像 + 逆元

在这里插入图片描述

由二次函数图像可以得到,最大值其实就是大于 0 的部分,S(b) - S(a)
之后把二次函数划开,分别求每一项的和,然后相加即可
在这里插入图片描述

逆元部分,一般除法有坑,除出来本来是有小数的,但是是整除,约去了,题目也没有说是向下整除,所以把除法—>乘法,利用逆元
本题的mod + 1 之后正好是整除 2 和 6 的,所以可以取巧的写

iv2 = (MOD + 1) / 2ll;
iv6 = (MOD + 1) / 6ll;

记得取模,ans 和 输出的 S(b) - S(a)
可以 加上MOD之后再取模,防止溢出;

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include<unordered_map>
#include <unordered_set>

using namespace std;

typedef long long ll;
const int N = 1e4 + 5;
const ll MOD = 998244353;
const ll iv2 = (MOD + 1) / 2ll;
const ll iv6 = (MOD + 1) / 6ll;
ll a, b;
ll S(int t) {
	ll ans1 = t * (t + 1ll) % MOD * (2ll * t + 1ll) % MOD * iv6 % MOD;
	ll ans2 = (a + b) * t % MOD * (t + 1ll) % MOD * iv2 % MOD;
	ll ans3 = a * b % MOD * t % MOD;
	ll ans = -ans1 + ans2 - ans3;
	ans = (ans % MOD + MOD) % MOD;
	return ans;
}

void solve() {
	scanf("%lld%lld", &a, &b);
	printf("%lld\n", (S(b) - S(a) + MOD) % MOD);
}

int main() {
	int T;
	scanf("%d", &T);
	while (T--)
		solve();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值