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 组学生在第 i 天都有空上课
- 第 2 组学生在第 j 天都有空上课
- i ! = j i\ !=j i !=j
题解
考虑到一共只有 5 天, i , j i,j i,j排列组合也就 10 种情况,所以可以枚举 i 和 j 判断是否合法。怎么样才合法呢
- 第 i i i 天 1 的数量 C 1 C_1 C1 要 ≤ n / 2 \le n/2 ≤n/2, 第 j j j 天 1 的数量 C 2 C_2 C2 也要 ≤ n / 2 \le n/2 ≤n/2,因为要分成两组,少于 n / 2 n/2 n/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+C2−C3 要等于 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×k−a[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),至少下面一项(都满足也行)
- a i ! = a j ! = a k a_i\ !=a_j\ !=a_k ai !=aj !=ak
- 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 Ca−1次计算 b k = = b i b_k==b_i bk==bi,举个例子,假如 C a = 4 C_a=4 Ca=4,那枚举 i , j i,j i,j的情况:
- i = 1 , j = 2 i=1,j=2 i=1,j=2
- i = 1 , j = 3 i=1,j=3 i=1,j=3
- i = 1 , j = 4 i=1,j=4 i=1,j=4
- i = 2 , j = 3 i=2,j=3 i=2,j=3
- i = 2 , j = 4 i=2,j=4 i=2,j=4
- i = 3 , j = 4 i=3,j=4 i=3,j=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;
}
}