比赛链接:
https://codeforces.com/contest/1598
A. Computer Game
题目大意:
由 1 和 0 组成的 2 行 \(n\) 列的地图,可以移动到 0 的格子,不能去 1 的格子,从(1, 1)出发,每一次都可以移动到周围的八个格子(不能移出地图),判断能不能到达(2, \(n\))。
思路:
显然,不能抵达终点的情况就是两行都是 1 的时候。
代码:
#include <bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(), (x).end()
#define fi first
#define LL long long
#define se second
const int N = 2e5 + 10;
const int mod = 1;
LL T = 1, n;
string a, b;
void solve(){
cin >> n >> a >> b;
for (int i = 0; i < n; i++)
if (a[i] == '1' && b[i] == '1'){
cout << "NO\n";
return;
}
cout << "YES\n";
}
int main(){
cin >> T;
while(T--)
solve();
return 0;
}
B. Groups
题目大意:
有 \(n\) (为偶数)个学生周一到周五的日程表,0 表示学生该日没空,1 表示有空,判断能不能将所有学生分成两组去上课,两组的学生数量要相同且他们在同一天都有空,但是两组有空的那一天要不同。
思路:
假设 \(x\) 和 \(y\) 分别为两组有空的那天,因为组合数很少,所以直接 暴力 跑出来。然后遍历所有学生,统计能不能找出两组这样的学生来。
代码:
#include <bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(), (x).end()
#define fi first
#define LL long long
#define se second
const int N = 2e5 + 10;
const int mod = 1;
LL T = 1, n;
int a[1010][10];
string s;
void solve(){
scanf("%lld", &n);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= 5; j++)
scanf("%d", &a[i][j]);
for (int x = 1; x <= 5; x++){
for (int y = x + 1; y <= 5; y++){
int s1 = 0, s2 = 0, s3 = 0;
for (int i = 1; i <= n; i++){
if (a[i][x] && a[i][y]) s3++;
else if (a[i][x]) s1++;
else if (a[i][y]) s2++;
}
if (s1 * 2 <= n && s2 * 2 <= n && s1 + s2 + s3 == n){
cout << "YES\n";
return;
}
}
}
cout << "NO\n";
}
int main(){
cin >> T;
while(T--)
solve();
return 0;
}
C. Delete Two Elements
题目大意:
给了长为 \(n\) 的整数序列,假设 \(k\) 是它的平均值,平均值可能是小数,计算去掉其中两个数 \(a_i 和 a_j (i < j)\) 之后序列的平均值不变的情况有几种。
思路:
假设 \(sum\) 是序列值的总和,去掉的数分别是 \(a_i\) 和 \(a_j\),那么可以得到 \(a_i\) + \(a_j\) = 2 * \(k\) = 2 * \(sum / n\),也就是 \((a_i + a_j) * n\) = 2 * \(sum\)。
我们可以先由小到大排序整个序列,那么对于 \(a_i\) 而言,满足条件的只能在它后面找,直接 二分 查找大于等于 \(2 * sum / n - a_i\) 的数即可,所有等于这个值的数的组合都是可以的。计算组合总数的话可以通过 \(map\) 去实现。
代码:
#include <bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(), (x).end()
#define fi first
#define LL long long
#define se second
const int N = 2e5 + 10;
const int mod = 1;
LL T = 1, n, a[N];
string s;
void solve(){
scanf("%lld", &n);
map <LL, int> mp;
for (int i = 1; i <= n; i++){
scanf("%lld", &a[i]);
mp[a[i]]++;
}
LL sum = 2 * accumulate(a + 1, a + n + 1, 0LL), ans = 0;
sort(a + 1, a + n + 1);
for (int i = 1; i < n; i++){
int p = lower_bound(a + i + 1, a + n + 1, sum / n - a[i]) - a;
mp[a[i]]--;
if ( (a[i] + a[p]) * n == sum) ans += mp[a[p]];
}
cout << ans << "\n";
}
int main(){
cin >> T;
while(T--)
solve();
return 0;
}
D. Training Session
题目大意:
思路:
代码:
题目大意:
思路:
代码: