[语言月赛 202308] 小粉兔的元素反应 题解
Source & Knowledge
2023 年 8 月语言月赛,由洛谷网校入门计划/基础计划提供。
题目大意
给定
题目分析
本题考察较复杂的模拟。
不难发现这样几条性质:
- 单个元素(
n = 1 )一定无法反应。 - 如果两个元素
a _ i, a _ j 可以反应,那么它们就可以一直反应,使得序列无限翻倍。 -
-
-
-
因此,对于每组数据,我们可以按照以下步骤处理:
k 的处理
由性质 3 和性质 4,我们使用字符串 std::string 或 char[] 读入
C++ 的 std::stoll() 可以将 std::string 转换为 long long 类型,这里使用这种方法进行转换。
string s;
cin >> s;
if (s.length() < 17) {
k = stoll(s);
} else {
k = 1e16;
}
对 n = 1 的特殊处理
对于
if (n == 1) {
if (a[1] >= k) {
cout << "Yes" << endl;
} else {
cout << "No" << endl;
}
continue;
}
直接判断当前元素是否总和 \geq k
我们只需读入时将所有元素相加,并与处理后的整数
找到可能反应的元素
由性质 5 和性质 6,我们可以遍历一次数组,找到能够整除
所以我们考虑分别记录能够整除
int cnt[15];
int ops[] = { 2, 3, 7, 11 };
memset(cnt, 0, sizeof(cnt));
for (int i = 1; i <= n; ++i) {
for (int j = 0 ; j < 4; ++j) {
if (a[i] % ops[j] == 0) {
++cnt[ops[j]];
}
}
}
首先我们可以扫描查找是否有直接为 Yes,进行下一组数据的运算。
如果没有,接下来,遍历数组查找能够整除
int flag = 0;
for (int i = 1; i <= n; ++i) {
if (a[i] % 154 == 0 || a[i] % 147 == 0) { cout << "Yes" << endl; flag = 1; break; }
if (a[i] % 21 == 0 && cnt[7] >= 2) { cout << "Yes" << endl; flag = 1; break; }
if (a[i] % 49 == 0 && cnt[3]) { cout << "Yes" << endl; flag = 1; break; }
if (a[i] % 77 == 0 && cnt[2]) { cout << "Yes" << endl; flag = 1; break; }
if (a[i] % 14 == 0 && cnt[11]) { cout << "Yes" << endl; flag = 1; break; }
if (a[i] % 22 == 0 && cnt[7]) { cout << "Yes" << endl; flag = 1; break; }
}
if (!flag)
cout << "No" << endl;
通过以上步骤,我们就可以完成所有判断。
视频讲解
视频题解后续将会上传。