ACWing 第49场周赛

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. 该子序列的所有元素之和必须是奇数。
  2. 在满足条件 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. 每个点的权值只能是 1 或 2 或 3。
  2. 对于图中的每一条边,其两端点的权值之和都必须是奇数。

请问,共有多少种不同的赋值方法。

由于结果可能很大,你只需要输出对 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值