ACWing 第49场周赛
A、组队
题目:
给定 nn 个整数 y1,y2,…,yn,及一个整数 k。
先求出有多少个 yi 满足 yi+k≤5,然后输出满足要求的 yi 的个数除以 3 下取整的值。
输入格式
第一行包含两个整数 n 和 k。
第二行包含 n 个整数 y1,y2,…,yn。
输出格式
一个整数,表示答案。
数据范围
前 44 个测试点满足 1≤n≤6。
所有测试点满足 1≤n≤2000,1≤k≤5,0≤yi≤5。
输入样例1:
5 2
0 4 5 1 0
输出样例1:
1
输入样例2:
6 4
0 1 2 3 4 5
输出样例2:
0
输入样例3:
6 5
0 0 0 0 0 0
输出样例3:
2
代码:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 2010;
int n, k, tmp, sum;
int main()
{
cin>>n>>k;
for(int i = 1; i <= n; i ++){
cin>>tmp;
if(tmp + k <= 5)sum++;
}
cout<< sum / 3 <<'\n';
return 0;
}
B、子序列
题目:
给定一个长度为 n 的整数序列 a1,a2,…,an。
请你找到一个该序列的子序列,要求:
- 该子序列的所有元素之和必须是奇数。
- 在满足条件 1 的前提下,该子序列的所有元素之和应尽可能大。
输出你找到的满足条件的子序列的所有元素之和。
保证至少存在一个满足条件的子序列。
注意,子序列不一定连续。
输入格式
第一行包含一个整数 n。
第二行包含 n 个整数 a1,a2,…,an。
输出格式
输出一个整数,表示满足条件的子序列的所有元素之和。
数据范围
前 66 个测试点满足 1≤n≤5。
所有测试点满足 1≤n≤105,−104≤ai≤104。
输入样例1:
4
-2 2 -3 1
输出样例1:
3
输入样例2:
3
2 -5 -3
输出样例2:
-1
代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int N = 1e5 + 5;
int n, a[N], sum = 0;
int main()
{
cin>>n;
int modd = N, food = - N;
for(int i = 1; i <= n; i ++){
cin>>a[i];
if(a[i] >= 0)sum += a[i];
if(a[i] >= 0 && a[i] % 2 == 1)modd = min(modd, a[i]);
if(a[i] < 0 && abs(a[i]) % 2 == 1)food = max(food, a[i]);
}
if(sum % 2 == 1){
cout<<sum<<'\n';
}
else{
sum -= min(abs(modd), abs(food));
cout<<sum<<'\n';
}
return 0;
}
C、点的赋值
题目:
给定一个 n个点 m 条边的无向无权图。
点的编号为 1∼n。
图中不含重边和自环。
现在,请你给图中的每个点进行赋值,要求:
- 每个点的权值只能是 1 或 2 或 3。
- 对于图中的每一条边,其两端点的权值之和都必须是奇数。
请问,共有多少种不同的赋值方法。
由于结果可能很大,你只需要输出对 998244353 取模后的结果。
输入格式
第一行包含整数 T,表示共有 T 组测试数据。
每组数据第一行包含两个整数 n,m。
接下来 m 行,每行包含两个整数 u,v,表示点 u 和点 v 之间存在一条边。
输出格式
一个整数,表示不同赋值方法的数量对 998244353 取模后的结果。
数据范围
输入样例:
2
2 1
1 2
4 6
1 2
1 3
1 4
2 3
2 4
3 4
输出样例:
4
0
思路分析:
通过对染色法判断一个图中的每个连通块是否是二分图,并且在染色的时候记录每个颜色染色的次数,因为二分图有两种颜色,且可以染成1,2,3,默认第一个颜色染第一个位置,如果第一个颜色是奇数,那么该连通块的方案数是2^x * 1y;如果第一个颜色是偶数,那么该连通块的方案数是1x + 2^y,两者之和即是该连通块的总染色方案数。如果该图是二分图,那么答案就是所有连通块的染色方案的乘积。
不知道二分图的点这里
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
const int N = 3e5 + 5, mod = 998244353;
vector<int>h[N];
int t, n, m, s1, s2;
int color[N];
int pow2(int k){
int res = 1;
while(k --){
res = 1ll * res * 2 % mod;
}
return res;
}
//c == 1 奇数 c == 2 偶数
int dfs(int u, int c){
color[u] = c;
if(c == 1)s1++;
else if(c == 2)s2++;
for(int i = 0; i < h[u].size(); i ++){
int& j = h[u][i];
if(!color[j]){
if(!dfs(j, 3 - c))return 0;
}
else if(color[j] == c)return 0;
}
return 1;
}
int main()
{
cin >> t;
while(t --){
cin >> n >> m;
for(int i = 1; i <= n; i ++)h[i].clear();
//h->clear();
// for(int i = 1; i <= n; i ++)cout<<"size:"<<h[i].size()<<' ';
// cout<<'\n';
memset(color, 0, (n + 1) * 4);
for(int i = 1; i <= m; i ++){
int a, b;
cin>>a>>b;
h[a].push_back(b);
h[b].push_back(a);
}
int ans = 1;
for(int i = 1; i <= n; i ++){
if(!color[i]){
s1 = 0;
s2 = 0;
if(dfs(i, 1))ans = 1ll * ans * (pow2(s1) + pow2(s2)) % mod;
else{
ans = 0;
break;
}
}
}
cout << ans << '\n';
}
return 0;
}