Codeforces Round #375 (Div. 2) 题解

本文精选了算法竞赛中的典型题目并提供了解题思路与代码实现,涵盖了贪心算法、图论、搜索等核心内容,适合算法爱好者及竞赛选手学习参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【A】水题,把x1,x2,x3排序之后,答案就是x2-x1。

【B】水题,模拟一下就好。

【复杂度】O(len)

【代码君】

//
//Created by just_sort 2016/10/3 18:45
//Copyright (c) 2016 just_sort.All Rights Reserved
//

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

string s1[300];
string s2[300];
int main()
{
    int n;
    cin>>n;
    string s;
    cin>>s;
    int cnt1 = 0,cnt2 = 0;
    string temp = "";
    bool flag = 0;
    for(int i = 0; s[i]; i++){
        if(s[i] == '_'){
            if(temp=="") continue;
            if(flag) s2[cnt2++] = temp;
            else s1[cnt1++] = temp;
            temp="";
        }
        else if(s[i] == '('){
            if(temp=="") {
                flag = 1;
                continue;
            }
            if(flag) s2[cnt2++] = temp;
            else s1[cnt1++] = temp;
            temp = "";
            flag = 1;
        }
        else if(s[i] == ')')
        {
            if(temp=="") {
                    flag = 0;
            continue;}
            if(flag) s2[cnt2++] = temp;
            else s1[cnt1++] = temp;
            temp = "";
            flag = 0;
        }
        else temp+=s[i];
    }
    if(temp!=""){
    if(flag) s2[cnt2++] = temp;
    else s1[cnt1++] = temp;
    }
    int ans1 = 0;
    for(int i = 0; i <cnt1; i++){
        ans1 = max(ans1,(int)s1[i].size());
    }
    printf("%d %d\n",ans1,cnt2);
}

【C】有一个序列a1,a2,…,an,现在定义bj表示数j在序列中出现的次数。问最小值bj(1≤j≤m)的最大可能值为多少,以及最少需要替换序列中的几个数?并输出替换之后的序列a1,a2,…,an。

【解题方法】贪心,过程如下:因为bj表示数j(1≤j≤m)在序列中出现的次数。而每个数出现的次数一开始是不一定的,这时候会存在一个最小值bj,即出现次数最少的那个数的出现次数。而这个最大可能值的含义是我们要替换一些数,使得出现次数最少的次数尽可能大。例如下面这组数据:

6 5

1 2 2 345 2134 885

最开始bj(1≤j≤m)分别为:

  j= 1 2 3 4 5

bj= 1 2 0 0 0

那此时bj最小值为0,为了使bj最小值尽可能大,我们需做如下替换:

2->3 345->4 2134->5

这样之后bj最小值为1,替换次数为3。由抽屉原理可知,bj最小值的最大可能值为n/m。而要使得bj(1≤j≤m)均达到n/m,那就必须将>m的数或是bj>n/m的数替换成bj<n/m的数。按照这个过程贪心就好了。

【代码君】

//
//Created by just_sort 2016/9/12 16:50
//Copyright (c) 2016 just_sort.All Rights Reserved
//

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;

const int maxn = 2222;
int a[maxn],b[maxn];
int n,m;
int main()
{
    cin>>n>>m;
    for(int i = 1; i <= n; i++)
    {
        cin>>a[i];
        if(a[i] <= m) b[a[i]]++;
    }
    int cnt = 0;
    for(int i = 1, j = 1; i <= n; i++)
    {
        while(j <= m && b[j] >= n / m) j++;
        if(j > m) break;
        if(a[i] > m || b[a[i]] > n / m)
        {
            if(a[i] <= m) b[a[i]]--;
            a[i] = j, b[j]++,cnt++;
        }
    }
    cout<<n/m<<" "<<cnt<<endl;
    for(int i = 1; i <= n; i++)
    {
        cout<<a[i]<<" ";
    }
}

【D】给你一个n/*m的矩阵,然后你们有不少于k条河流,然后你需要使得一些河流变成陆地,使得河流的数量恰好等于k,问你至少填多少个水。河流的定义是水塘,且不与外界相连的地方。

【解题方法】直接dfs搜出每一条河流,然后贪心排序,从小到大去填满就好了。

【代码君】

//
//Created by just_sort 2016/9/12 16:50
//Copyright (c) 2016 just_sort.All Rights Reserved
//

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 55;
const int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
int n,m,k;
char s[maxn][maxn];
int vis[maxn][maxn];
int area,flag,cnt;
void dfs1(int x,int y)
{
    area++;
    vis[x][y] = 1;
    if(x == 0 || x == n-1 || y == 0 || y == m-1) flag = 1;
    for(int i = 0; i < 4; i++)
    {
        int dx = x + dir[i][0];
        int dy = y + dir[i][1];
        if(dx < 0 || dx >= n) continue;
        if(dy < 0 || dy >= m) continue;
        if(s[dx][dy] == '*') continue;
        if(vis[dx][dy]) continue;
        dfs1(dx,dy);
    }
}
void dfs2(int x,int y)
{
    s[x][y] = '*';
    for(int i = 0; i < 4; i++)
    {
        int dx = x + dir[i][0];
        int dy = y + dir[i][1];
        if(dx < 0 || dx >= n) continue;
        if(dy < 0 || dy >= m) continue;
        if(s[dx][dy] == '*') continue;
        dfs2(dx,dy);
    }
}
struct node{
    int a,b,c;
    bool operator<(const node &rhs) const{
        return a < rhs.a;
    }
}t[5000];

int main()
{
    cin>>n>>m>>k;
    for(int i = 0; i < n; i++) cin>>s[i];
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            if(!vis[i][j] && s[i][j] == '.'){
                area = 0;
                flag = 0;
                dfs1(i,j);
                if(flag == 1) continue;
                t[cnt].a = area,t[cnt].b = i,t[cnt].c = j;
                cnt++;
            }
        }
    }
    sort(t,t+cnt);
    int ans = 0;
    for(int i = 0; i < cnt - k; i++){
        ans += t[i].a;
        dfs2(t[i].b,t[i].c);
    }
    cout<<ans<<endl;
    for(int i = 0; i < n; i++){
        cout<<s[i]<<endl;
    }
}

【E】给你一个无向图,然后让你给边定向,使得入度等于出度的点最多。

【解题方法】考虑欧拉图,只要所有点的度数为偶数就可以了。那么答案就是奇数度数的点集,然后我们不停的dfs,把欧拉路都画出来就行了。

【代码君】

//
//Created by just_sort 2016/9/12 16:50
//Copyright (c) 2016 just_sort.All Rights Reserved
//

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 222;
set <int> g[maxn];
vector<pair<int,int> >ans;
int n,m,degree[maxn];
void init(){
    memset(degree,0,sizeof(degree));
    for(int i = 0; i < maxn; i++) g[i].clear();
    ans.clear();
}
void dfs(int u){
    while(g[u].size()){
        int v = *g[u].begin();
        g[u].erase(v);g[v].erase(u);
        if(u != n+1 && v != n+1) cout<<u<<" "<<v<<endl;
        dfs(v);
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        init();
        cin>>n>>m;
        while(m--){
            int u,v;
            cin>>u>>v;
            g[u].insert(v);
            g[v].insert(u);
            degree[u]++,degree[v]++;
        }
        int sum = 0;
        for(int i = 1; i <= n; i++){
            if(degree[i]&1){
                sum++,g[i].insert(n+1),g[n+1].insert(i);
            }
        }
        cout<<n-sum<<endl;
        for(int i = 1; i <= n; i++) dfs(i);
    }
    return 0;
}

【F】留坑待填
资源下载链接为: https://pan.quark.cn/s/1bfadf00ae14 “STC单片机电压测量”是一个以STC系列单片机为基础的电压检测应用案例,它涵盖了硬件电路设计、软件编程以及数据处理等核心知识点。STC单片机凭借其低功耗、高性价比和丰富的I/O接口,在电子工程领域得到了广泛应用。 STC是Specialized Technology Corporation的缩写,该公司的单片机基于8051内核,具备内部振荡器、高速运算能力、ISP(在系统编程)和IAP(在应用编程)功能,非常适合用于各种嵌入式控制系统。 在源代码方面,“浅雪”风格的代码通常简洁易懂,非常适合初学者学习。其中,“main.c”文件是程序的入口,包含了电压测量的核心逻辑;“STARTUP.A51”是启动代码,负责初始化单片机的硬件环境;“电压测量_uvopt.bak”和“电压测量_uvproj.bak”可能是Keil编译器的配置文件备份,用于设置编译选项和项目配置。 对于3S锂电池电压测量,3S锂电池由三节锂离子电池串联而成,标称电压为11.1V。测量时需要考虑电池的串联特性,通过分压电路将高电压转换为单片机可接受的范围,并实时监控,防止过充或过放,以确保电池的安全和寿命。 在电压测量电路设计中,“电压测量.lnp”文件可能包含电路布局信息,而“.hex”文件是编译后的机器码,用于烧录到单片机中。电路中通常会使用ADC(模拟数字转换器)将模拟电压信号转换为数字信号供单片机处理。 在软件编程方面,“StringData.h”文件可能包含程序中使用的字符串常量和数据结构定义。处理电压数据时,可能涉及浮点数运算,需要了解STC单片机对浮点数的支持情况,以及如何高效地存储和显示电压值。 用户界面方面,“电压测量.uvgui.kidd”可能是用户界面的配置文件,用于显示测量结果。在嵌入式系统中,用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值