Educational Codeforces Round 115 (Rated for Div. 2)
Posted MangataTS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Educational Codeforces Round 115 (Rated for Div. 2)相关的知识,希望对你有一定的参考价值。
A. Computer Game(思维)
题意
给你一个 2 × n 2\\times n 2×n的地图,然后你从左上角的位置往右下角移动,每次可以往八个方向前进一个单位,但是落脚点必须是0
思路
我们发现其实当第一行的第 i i i个元素和第二行的第 i i i个元素相等的时候并且等于1,那么就不能到达目的地
CODE
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5+10;
int t,n;
string mp[2];
int main()
{
cin>>t;
while(t--) {
cin>>n;
cin>>mp[0]>>mp[1];
bool fg = true;
for(int i = 0;i < n; ++i) {
if(mp[0][i] == mp[1][i] && mp[0][i] == '1') fg = false;
}
if(fg) puts("YES");
else puts("NO");
}
return 0;
}
B. Groups(枚举)
题意
给你n(n为偶数)个学生的周内上课表,然后让你给这n个学生分为2组在不同的两天上课,问你能否满足有一种安排情况,使得两组的同学的人数相等
思路
首先,因为每个学生的上课时间是固定了的也就是5天,那么我们就直接枚举两天即可,注意两天不同
- 我们统计两列信息的时候我们需要分别统计那天能上课的同学人数,以及都能上课的人数
- 显然当都能上课的人数小于n的时候,那么就不满足了
- 当左侧的同学人数和右侧的同学的人数都小于 n / 2 n/2 n/2的时候那也不满足
- 剩下的情况就满足(详情看代码)
CODE
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5+10;
int t,n;
int mp[N][6];
bool check(int l,int r) {//检测l和r这两天能不能满足情况
int lk,rk,tol;
lk = rk = tol = 0;
for(int i = 1;i <= n; ++i) {
if(mp[i][l]) lk++;
if(mp[i][r]) rk++;
if(mp[i][l]||mp[i][r]) tol++;
}
int k = n/2;
if(lk >= k && rk >= k && tol == n) return true;//满足情况返回true
return false;
}
int main()
{
cin>>t;
while(t--) {
cin>>n;
for(int i = 1;i <= n; ++i) {
for(int j = 1;j <= 5; ++j) {
cin>>mp[i][j];
}
}
for(int i = 1;i <= 5; ++i) {
for(int j = i + 1;j <= 5; ++j) {
if(check(i,j)){//如果找到了满足的条件,那么就直接goto出去了
puts("YES");
goto out;
}
}
}
puts("NO");
out:;
}
return 0;
}
C. Delete Two Elements(map+逆元)
题意
给你n个数,然后有一个
k = ∑ i = 0 n a [ i ] n k =\\frac{\\sum_{i=0}^n a[i]}{n} k=n∑i=0na[i]
在这n个元素中选取两个元素删除,然后k值不变的情况的数量有多少种
思路
首先来说删除的这两个数的和肯定和k*2相等,所以我们可以用用map记录下来每次删除的元素的个数,当然k的计算可能会不能整除,所以我们可以用逆元处理一下(因为数据是小于等于1e9的),于是得到了如下代码
CODE
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000007
const int N = 2e5+10;
ll t,n;
ll qpow(ll a,ll b,ll c) {
ll ans = 1;
while(b) {
if(b & 1) ans = (ans * a) % c;
b >>= 1;
a = (a * a) % c;
}
return ans;
}
ll inv(ll x,ll c) {//逆元
return qpow(x,c-2,c);
}
ll a[N];
map<ll,ll> vis;
int main()
{
cin>>t;
while(t--) {
vis.clear();
cin>>n;
ll sum = 0;
for(int i = 0;i < n; ++i) {
cin>>a[i];
sum += a[i];
}
ll kk = (((2LL * sum) % mod) * inv(n,mod)) % mod;
ll ans = 0;
for(int i = 0;i < n; ++i) {
ans += vis[(kk-a[i] + mod) % mod];
vis[a[i]]++;
}
cout<<ans<<"\\n";
}
return 0;
}
D. Training Session(组合数)
题意
给你n个问题,每个问题有两个指标:top和difficulties ,我们需要选取三个问题找到满足以下条件的组合情况
- 三个问题的topics不同
- 三个问题的difficulties 不同
思路
首先我们可以计算出选取的总情况数: C n 3 = n ∗ ( n − 1 ) ∗ ( n − 2 ) / 6 C_n^3 = n * (n-1) * (n-2)/6 Cn3=n∗(n−1)∗(n−2)/6 ,然后我们从反向思考找到不满足情况,我们以第i个位置得问题作为中心点,则再需要一组其他位置得元素得值即可构成不满足条件得情况,那么我们就可以直接统计这种情况的数量
官方思路:
CODE
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e5+10;
ll t,n;
map<ll,ll> vis1,vis2;
ll a[N],b[N];
vector<ll> V1,V2;
int main()
{
cin>>t;
while(t--) {
vis1.clear();
vis2.clear();
cin>>n;
ll ans = (n * (n-1) / 2LL) * (n-2) / 3LL;
for(int i = 0;i < n; ++i) {
scanf("%lld%lld",&a[i],&b[i]);
vis1[a[i]]++;
vis2[b[i]]++;
}
for(int i = 0;i < n; ++i) {
ans -= (vis1[a[i]] - 1) * (vis2[b[i]] - 1);//减去不满足条件的情况,以当前这个元素为中心计算
}
cout<<ans<<endl;
}
return 0;
}
以上是关于Educational Codeforces Round 115 (Rated for Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章
Educational Codeforces Round 7 A
Educational Codeforces Round 7
Educational Codeforces Round 90
Educational Codeforces Round 33