比赛链接:https://codeforces.com/contest/1492
1492A.Three swimmers
题意:
有三名游泳的人,他们分别需要 分钟才能在一个游泳池游一个来回,第一个游泳者将在开始时间
分钟后在游泳池的左侧,第二个游泳者将在
分钟后,第三个将在
分钟后出现在池的左侧。
分钟后最少需要等待多长时间会有一个游泳者到达游泳池左侧。
思路:
签到题,
可以暴力遍历 寻找最小值,
也可以直接找 的倍数离
差多少
注意开 long long….
【AC Code】
int main() {ios::sync_with_stdio(false), cin.tie(nullptr);int _; for (cin >> _; _--;) {ll p, a, b, c;cin >> p >> a >> b >> c;if (p % a == 0 || p % b == 0 || p % c == 0)cout << "0\n";else cout << min(a - p % a, min(b - p % b, c - p % c)) << "\n";}}
1492B. Card Deck
题意:
有 张卡,每张卡的值
,等于
,
代表底卡,
是顶卡,在每个步骤中,选择一些
的整数,从原始卡片组中取出前
张卡片,然后按它们现在的顺序将它们放置在新卡片组的顶部。让阶数最大。
思路:
找最大的数输出最大的数加后边的所有数,接着找第二个······注意不要重复输出
【AC Code】
const int N = 1e5 + 10;ll a[N], pos[N];bool st[N];int main() {ios::sync_with_stdio(false), cin.tie(nullptr);int _; for (cin >> _; _--;) {vector<int>A;int n; cin >> n;for (int i = 1; i <= n; ++i) {cin >> a[i];pos[i] = i;st[a[i]] = 0;}ll t = n;for (ll i = n; i >= 1; i -= 1) {if (a[i] == t)for (ll j = i; !st[a[j]] && j <= n; j += 1) {st[a[j]] = 1;A.emplace_back(a[j]);}while (st[t] && t >= 1) t -= 1;}for (ll i = 0; i < n; i += 1) cout << A[i] << " \n"[i == n - 1];}}
1492C. Maximum width
题意:
给你两个字符串 找
串和
串匹配的下标,然后找相邻下标之间的最大值,管你懂不懂看样例就完事了
思路:
看了半天样例发现只需要前后扫一遍,分别用两个数组去存前后扫的下标结果,取两个数组相邻位置的最大值
【AC Code】
const int N = 2e5 + 10;int n, m, a[N], b[N];string s, t;int main() {ios::sync_with_stdio(false), cin.tie(nullptr);cin >> n >> m >> s >> t;int i = 0, j = 0;while (j < m) {if (s[i] == t[j]) {a[j] = i + 1;i ++; j ++;} else i ++;}i = n - 1, j = m - 1;while (j > 0) {if (s[i] == t[j]) {b[j] = i + 1;i --; j --;} else i --;}int ans = 0;for (int q = 0; q < m; q ++)ans = max(ans, b[q + 1] - a[q]);cout << ans << "\n";}
1492D. Genius’s Gambit
题意:
给你三个数, 代表
的个数,
代表
的个数,
代表
中
的个数,让你求出
满足
三个条件,如果没有输出
NO
思路:
构造题,说实话赛时没构造出来,这里参考了一下题解
由题目可知
是肯定的,所以我们不妨假设
,然后对
进行变换,我们发现
最右边的1往后移动一位
的值就多一个
,最大为
,然后移动倒数第二个
,发现只能移动一次,如果移动两次不会多一个
。
假设
x 1110000
y 1110000当
的倒数第一个
往右移动时发现
中
的个数
,当y 1100001时
中
的个数为
,然后移动倒数第二个
,移动一次,发现
中
的个数变成了
,再移动一次发现又变回
,所以除了倒数第一个
可以移动多次,第一个
不能移动中间的
只能移动一次,我们可以找出规律,最大的值为
。
【AC Code】
int a, b, k;int main(void) {cin.tie(0);ios::sync_with_stdio(false);cin >> a >> b >> k;if (k == 0) {cout << "Yes" << '\n';string x = "", y = "";x += '1';b--;for (int i = 0; i < a; i++) x += '0';for (int i = 0; i < b; i++) x += '1';cout << x << '\n';cout << x << '\n';return 0;}k--;if (a > 0 && b >= 2 && (a + b - 3 >= k)) {cout << "Yes" << '\n';string x = "";string y = "";a--; b -= 2;x += '1'; y += '1';x += '1'; y += '0';for (int i = 0; i < k; i++) {if (a) {a--;x += '0'; y += '0';} else {b--;x += '1'; y += '1';}}x += '0'; y += '1';while (a--) {x += '0'; y += '0';}while (b--) {x += '1'; y += '1';}cout << x << '\n';cout << y << '\n';} elsecout << "No" << '\n';}
模拟构造,我不会(QAQ
1492E. Almost Fault-Tolerant Database
题意:
给定 个长度为
的数组,需要输出一个长度为
的数组,使得这些数组之间不同的数不超过两个,输出YES,输出你构造的数组,若有多种情况,可任意输出一种。如若不存在,输出NO。
思路:
假设第一个数组为标准数组,遍历
- 不同数小于等于
,没问题
- 不同数大于
,直接输出NO
- 就是
的情况,我们找差异数最大的那个也就是
的情况,枚举修改的两个位置,判断是否可以成立。
【AC Code】
const int N = 250010;int n, m;vector <int> s[N];bool check2(vector<int> &v) {for (int i = 1; i < n; i ++) {int cnt = 0;for (int j = 0; j < m; j ++)if (s[i][j] != v[j]) cnt ++;if (cnt > 3) return false;else if (cnt == 3) {int ans = 1;for (int j = 0; j < m; j ++) {if (s[i][j] != v[j] && v[j] == -1) {ans = 0;v[j] = s[i][j];break;}}if (ans) return false;}}return true;}bool check() {int cnt = 0, ax = 0, id;for (int i = 1; i < n; i ++) {int ans = 0;for (int j = 0; j < m; j ++)if (s[i][j] != s[0][j]) ans ++;if (ans > 4) return false;if (ans <= 2) cnt ++;if (ans > ax)ax = ans, id = i;}if (cnt == n - 1) {cout << "Yes\n";for (int i = 0; i < m; ++i) cout << s[0][i] << " \n"[i == m - 1];return true;}vector<int> a;for (int i = 0; i < m; i ++)if (s[0][i] != s[id][i]) a.push_back(i);for (int i = 0; i < a.size(); i ++) {for (int j = 0; j < a.size(); j ++) {if (i == j) continue;vector<int> b = s[0];b[a[i]] = s[id][a[i]];b[a[j]] = -1;if (check2(b)) {cout << "Yes\n";for (int i = 0; i < m; ++i) cout << (b[i] == -1 ? s[0][i] : b[i]) << " \n"[i == m - 1];return true;}}}return false;}int main() {ios::sync_with_stdio(false), cin.tie(nullptr);cin >> n >> m;for (int i = 0; i < n; i ++) {for (int j = 0, x; j < m; j ++) {cin >> x;s[i].push_back(x);}}if (!check()) puts("No");}
