A Computer Game
题目大意
给定两个长度为n的01串,0能通过,1不能通过,问能否从(1, 1)走到(2, n)
主要思路
只要从1到n的任意位置不存在上下两个全是1的情况即可
AC代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
#define debug(a) cout << #a << " = " << a << endl;
#define x first
#define y second
typedef long long ll;
const int N = 500010, mod = 1e9+7;
int n, m;
signed main(void)
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin >> T;
while(T--)
{
cin >> n;
bool flag = true;
string s[10];
for(int i = 1; i <= 2; i++)
{
cin >> s[i];
}
if(s[1][0] == 1) flag = false;
else
{
for(int i = 0; i < n; i++)
{
if(s[1][i] == '1' && s[2][i] == '1') flag = false;
}
}
if(flag) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}
B Groups
题目大意
给定n个人,每个人都有想去的的周几的课,让你把这些学生分成人数相同的两队,并且每队的学生都愿意去某一节课,且两队去的课不能相同
主要思路
暴力枚举每一队选择哪两天,假设第一队选择i,第二队选择j
首先判断出愿意在i且不愿意在j的人数cnti,愿意在j不愿意在i的人数cntj,以及即愿意在i也愿意在j的人数cnt,如果有人既不愿意在i也不愿意在j那么不能分成两队一定不合法
其次我们只要让cnt分给cnti和cntj让这两个值相等即可
假设cnti + cnt < cntj || cntj + cnt < cnti这样一定不能让cnti和cntj相等,其余情况均可
AC代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
#define debug(a) cout << #a << " = " << a << endl;
#define x first
#define y second
typedef long long ll;
const int N = 1010, mod = 1e9+7;
int n, m;
int a[N][10];
int st[N];
bool check(int x, int y)
{
int cntx = 0, cnty = 0, cnt = 0;
for(int i = 1; i <= n; i++)
{
if(a[i][x] && !a[i][y]) cntx++;
else if(!a[i][x] && a[i][y]) cnty++;
else if(a[i][x] && a[i][y])
{
cnt++;
}
else return false;
}
if(cntx + cnt < cnty || cnty + cnt < cntx) return false;
else return true;
}
signed main(void)
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin >> T;
while(T--)
{
cin >> n;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= 5; j++)
{
cin >> a[i][j];
}
}
bool flag = false;
for(int i = 1; i <= 5; i++)
{
for(int j = i + 1; j <= 5; j++)
{
if(check(i, j)) flag = true;
}
}
if(flag) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}
C Delete Two Elements
题目大意
给定k个数,让你在k个数中任选两个数使其剩下的k-2个数的平均值与k个数的平均值相同,问有多少种选法
主要思路
首先假设n个数平均值为k,k * 2为任选的两个数的和
- 假设这个数不为整数,那么一定返回0,因为输入n个数都为整数,(a + b) / 2 == sum / n,于是sum * 2 / n == a + b,由于a + b是整数,所以(sum * 2) % n == 0
- 然后我们对数组记录每个数出现的次数,然后排序+去重
- 遍历排序去重后的数组,对每个数二分找两个数的和与k*2相等的数,加上两个数个数的乘积即可
AC代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
#define debug(a) cout << #a << " = " << a << endl;
#define x first
#define y second
typedef long long ll;
const int N = 200010, mod = 1e9+7;
const double eps = 1e-8;
int n, m;
signed main(void)
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin >> T;
while(T--)
{
unordered_map<int, int> st;
cin >> n;
vector<int> a(n);
int sum = 0;
for(int i = 0; i < n; i++) cin >> a[i], sum += a[i], st[a[i]]++;
sort(a.begin(), a.end());
a.erase(unique(a.begin(), a.end()), a.end());
//debug(a.size())
double k = sum * 1.0 / n;
if((sum * 2) % n != 0)
{
cout << 0 << endl;
continue;
}
int ans = 0;
for(int i = 0; i < a.size(); i++)
{
int l = 0, r = a.size() - 1;
while(l < r)
{
int mid = l + r >> 1;
if((a[i] + a[mid]) * 1.0 / 2 >= k) r = mid;
else l = mid + 1;
}
if((a[i] + a[l]) == k * 2)
{
if(a[i] != a[l]) ans += st[a[i]] * st[a[l]], st[a[i]] = 0, st[a[l]] = 0;
else ans += st[a[i]] * (st[a[i]] - 1) / 2, st[a[i]] = 0;
}
}
cout << ans << endl;
}
return 0;
}
D Training Session
题目大意
给定n对(x, y),问从中选出3对且这3对不存在x有相同且y有相同,问能选出多少组合
主要思路
正着计算不好计算我们考虑反着算,先计算出n个数中任选3个数情况是n * (n - 1) * (n - 2) / 6,然后减去选出的3各种x有相同且y有相同的情况
我们先统计出每一个x出现的次数和每一个y出现的次数,然后从1开始遍历,答案每次减去当前遍历到的x和当前遍历到的y的(x - 1)*(y - 1)的乘积,每次要除去自己本身,在其他x中任取一个以及在其他y中任取一个,由于不存在两队x和y相同,所以不存在重复情况
AC代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
#define debug(a) cout << #a << " = " << a << endl;
#define x first
#define y second
typedef long long ll;
const int N = 200010, mod = 1e9+7;
int n, m;
pair<int, int> a[N];
signed main(void)
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin >> T;
while(T--)
{
unordered_map<int, int> mpx, mpy;
cin >> n;
for(int i = 0; i < n; i++)
{
cin >> a[i].x >> a[i].y;
mpx[a[i].x]++, mpy[a[i].y]++;
}
int ans = n * (n - 1) * (n - 2) / 6;
for(int i = 0; i < n; i++)
{
ans -= (mpx[a[i].x] - 1) * (mpy[a[i].y] - 1);
}
cout << ans << endl;
}
return 0;
}