Educational Codeforces Round 115 (Rated for Div. 2)【A~D】

文章目录

A

题意

给出一个 2 × n 2 \times n 2×n 的矩阵,起点 ( 1 , 1 ) (1, 1) (1,1) 终点 ( 2 , n ) (2, n) (2,n),每次可以走到
相邻的格子(包括对角),矩阵中 0 表示空地,1 表示障碍,问能否走到终点

题解

只要 ( 1 , x ) , ( 2 , x ) (1,x),(2,x) (1,x)(2,x) 不同时为 1 就能走到

#include<iostream>
#include<sstream>
#include<string>
#include<queue>
#include<map>
#include<unordered_map>
#include<set>
#include<vector>
#include<stack>
#include <utility>
#include<list>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<time.h>
#include<random>
using namespace std;
#include<ext/pb_ds/priority_queue.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace __gnu_pbds;
#include<ext/rope>
using namespace __gnu_cxx;

#define int long long
#define PI acos(-1.0)
#define eps 1e-9
#define lowbit(a) ((a)&-(a))

const int mod = 1e9+7;
int qpow(int a,int b){
	int ans=1;
	while(b){
		if(b&1)ans=(ans*a)%mod;
		a=(a*a)%mod;
		b>>=1;
	}
	return ans;
}
const int INF = 0x3f3f3f3f;
const int N = 1e6+10;

#define endl '\n'
signed main(){
	std::ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int t; cin>>t;
	while(t--){
		int n; cin>>n;
		string s1,s2; cin>>s1>>s2;
		int flag=1;
		for(int i=0;i<n;i++)
			if(s1[i]=='1'&&s2[i]=='1')flag=0;
		cout<<(flag?"YES":"NO")<<endl;
	}
}


B

题意

n n n 个学生( n n n 为偶数),对于每个学生给出 5 5 5 个数,其中第 i i i 个数 a i a_i ai 表示该学生能否在星期 i i i 上课。能否把学生分成两组使:

  1. 第 1 组学生在第 i 天都有空上课
  2. 第 2 组学生在第 j 天都有空上课
  3. i   ! = j i\ !=j i !=j

题解

考虑到一共只有 5 天, i , j i,j ij排列组合也就 10 种情况,所以可以枚举 ij 判断是否合法。怎么样才合法呢

  1. i i i1 的数量 C 1 C_1 C1 ≤ n / 2 \le n/2 n/2, 第 j j j1 的数量 C 2 C_2 C2 也要 ≤ n / 2 \le n/2 n/2,因为要分成两组,少于 n / 2 n/2 n/2 肯定分不成一组
  2. i , j i,j i,j两天共同是 1 的数量为 C 3 C_3 C3, 则 C 1 + C 2 − C 3 C_1+C_2-C_3 C1+C2C3 要等于 n n n ,因为是 n n n分成两组,那么每组的人加起来应该等于 n n n,两组人数之和就是 i , j i,j i,j 两天可以去的人数之和减去重回部分 C 3 C_3 C3

在这里插入图片描述

#include<iostream>
#include<sstream>
#include<string>
#include<queue>
#include<map>
#include<unordered_map>
#include<set>
#include<vector>
#include<stack>
#include <utility>
#include<list>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<time.h>
#include<random>
using namespace std;
#include<ext/pb_ds/priority_queue.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace __gnu_pbds;
#include<ext/rope>
using namespace __gnu_cxx;

#define int long long
#define PI acos(-1.0)
#define eps 1e-9
#define lowbit(a) ((a)&-(a))

const int mod = 1e9+7;
int qpow(int a,int b){
	int ans=1;
	while(b){
		if(b&1)ans=(ans*a)%mod;
		a=(a*a)%mod;
		b>>=1;
	}
	return ans;
}
const int INF = 0x3f3f3f3f;
const int N = 1e6+10;
int a[1004][6];

#define endl '\n'
signed main(){
	std::ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int t; cin>>t;
	while(t--){
		int n; cin>>n;
		for(int i=1;i<=n;i++)
			for(int j=1;j<=5;j++)
				cin>>a[i][j];
		int flag=0;
		for(int i=1;i<=5;i++){
			for(int j=1;j<=5;j++){
				if(i==j)continue;
				int c1=0,c2=0,c3=0;
		//c1表示第i天1的数量,c2表示第j天1的数量,c3是i、j同时为1的数量
				for(int k=1;k<=n;k++){
					if(a[k][i])c1++;
					if(a[k][j])c2++;
					if(a[k][i]&&a[k][j])c3++;
				}
				if(c1>=n/2&&c2>=n/2&&c1+c2-c3>=n)flag=1;
			}
		}
		cout<<(flag?"YES":"NO")<<endl;
	}
}


C

题意

给出一个序列 a [ 1... n ] a[1...n] a[1...n] ,设这个序列平均数为 k k k ,求有多少对 ( i , j ) (i, j) (i,j) 使序列删去 a [ i ] 、 a [ j ] a[i]、a[j] a[i]a[j] 之后平均数不变

题解

map记录一下每个数出现的次数,然后枚举 a [ i ] a[i] a[i] ,要使 k k k 不变,则 a [ j ] = 2 × k − a [ i ] a[j]=2\times k-a[i] a[j]=2×ka[i],然后 a n s + = m a p [ a [ j ] ] ans+=map[ a[j] ] ans+=map[a[j]] 就好了

#include<iostream>
#include<sstream>
#include<string>
#include<queue>
#include<map>
#include<unordered_map>
#include<set>
#include<vector>
#include<stack>
#include <utility>
#include<list>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<time.h>
#include<random>
using namespace std;
#include<ext/pb_ds/priority_queue.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace __gnu_pbds;
#include<ext/rope>
using namespace __gnu_cxx;

#define int long long
#define PI acos(-1.0)
#define eps 1e-9
#define lowbit(a) ((a)&-(a))

const int mod = 1e9+7;
int qpow(int a,int b){
	int ans=1;
	while(b){
		if(b&1)ans=(ans*a)%mod;
		a=(a*a)%mod;
		b>>=1;
	}
	return ans;
}
const int INF = 0x3f3f3f3f;
const int N = 1e6+10;
int a[N];
map<int,int>mp;

#define endl '\n'
signed main(){
	std::ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int t; cin>>t;
	while(t--){
		mp.clear();
		int n; cin>>n;
		double k=0;
		for(int i=1;i<=n;i++)cin>>a[i],k+=a[i],mp[a[i]]++;
		k=1.0*k/n;
		int ans=0;
		for(int i=1;i<=n;i++){
			mp[a[i]]--; 
			//因为枚举的是a[i],为了防止加重了,得先把a[i]次数减1
			double g=k*2-a[i];//求a[j]
			if(g!=(int)g)continue;//a[j]不是整数,不合法
			ans+=mp[(int)g];//记得强转,a[j]是double类型
		}
		cout<<ans<<endl;
	}
}


D

题意

N N N 个项目,每个项目 i i i 有两种属性:项目主题 a i a_i ai 和 项目难度 b i b_i bi
求有多少对 ( i , j , k ) (i, j, k) (i,j,k),至少下面一项(都满足也行)

  1. a i   ! = a j   ! = a k a_i\ !=a_j\ !=a_k ai !=aj !=ak
  2. b i   ! = b j   ! = b k b_i\ !=b_j\ !=b_k bi !=bj !=bk

题解

如果从正面考虑有多少种合法的情况很麻烦:要计算满足①的,满足②的,还要减去重合部分——同时满足①②的。那就从反面想,用总数减去不合法的——即 a a a 有相同的,且 b b b 也有相同的。

那我们可以这样考虑,枚举两个 a a a 相等的 i , j i,j i,j(注意不是3个,三个的话 b b b 就全不一样了),然后看有多少个 b k = = b i b_k==b_i bk==bi 或者多少个 b k = = b j b_k==b_j bk==bj ,但是枚举 i , j i,j i,j 肯定超时,但是我们注意到 b i b_i bi b j b_j bj 的计数是独立的,假如枚举的 a a a 共有 C a C_a Ca 个,那么对于 i i i ,就会有 C a − 1 C_a-1 Ca1次计算 b k = = b i b_k==b_i bk==bi,举个例子,假如 C a = 4 C_a=4 Ca=4,那枚举 i , j i,j i,j的情况:

  1. i = 1 , j = 2 i=1,j=2 i=1j=2
  2. i = 1 , j = 3 i=1,j=3 i=1j=3
  3. i = 1 , j = 4 i=1,j=4 i=1j=4
  4. i = 2 , j = 3 i=2,j=3 i=2j=3
  5. i = 2 , j = 4 i=2,j=4 i=2j=4
  6. i = 3 , j = 4 i=3,j=4 i=3j=4

不难发现,在①②③次中需要计算 b k = = b i 1 b_k==b_{i_1} bk==bi1,在②④⑤次中需要计算 b k = = b i 2 b_k==b_{i_2} bk==bi2,在②④⑥次中需要计算 b k = = b i 3 b_k==b_{i_3} bk==bi3,在③⑤⑥次中需要计算 b k = = b i 4 b_k==b_{i_4} bk==bi4

#include<iostream>
#include<sstream>
#include<string>
#include<queue>
#include<map>
#include<unordered_map>
#include<set>
#include<vector>
#include<stack>
#include <utility>
#include<list>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<time.h>
#include<random>
using namespace std;
#include<ext/pb_ds/priority_queue.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace __gnu_pbds;
#include<ext/rope>
using namespace __gnu_cxx;

#define int long long
#define PI acos(-1.0)
#define eps 1e-9
#define lowbit(a) ((a)&-(a))

const int mod = 1e9+7;
int qpow(int a,int b){
	int ans=1;
	while(b){
		if(b&1)ans=(ans*a)%mod;
		a=(a*a)%mod;
		b>>=1;
	}
	return ans;
}
const int INF = 0x3f3f3f3f;
const int N = 1e6+10;
int ca[N],cb[N];
vector<int>g[N]; 
#define endl '\n'
signed main(){
	std::ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int t; cin>>t;
	while(t--){
		int n; cin>>n;
		for(int i=1;i<=n;i++)g[i].clear();
		for(int i=1;i<=n;i++)ca[i]=cb[i]=0;
		for(int i=1;i<=n;i++){
			int a,b; cin>>a>>b;
			ca[a]++,cb[b]++;//ca为a出现次数,cb为b出现次数
			g[a].push_back(b);//记录每一个a有哪几种b
		}
		int tot=n*(n-1)*(n-2)/6;//总数
		for(int i=1;i<=n;i++){
			if(ca[i]<2) continue;
			//假如i次数小于2次,那a就不存在不合法状态
			for(int j=0;j<ca[i];j++)
				tot-=(ca[i]-1)*(cb[g[i][j]]-1);
		}
		cout<<tot<<endl;
	}
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值