codeforces1251

本文精选了五道算法竞赛题目并提供了详细的解题思路及代码实现,包括键盘故障字符识别、字符串回文构造、数字重组、员工工资分配及投票策略等,深入探讨了贪心、二分查找和优先队列等算法的应用。

A.

题意:一个键盘坏了,坏的健按一下会出两个字母,给一串这个坏键盘打出来的字母,问你哪个键有可能坏了。

思路:连续奇数不可能,连续偶数有可能。

#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int main()
{
    string str;
    int n;
	int m;
    int num[1005];
    cin>>n;
    while(n--)
    {
        int cnt=1;
        memset(num,0,sizeof num);
        cin>>str;
        for(int i=1;i<=str.length();i++)
            if(str[i]==str[i-1])    
                cnt++;
            else
            {
                if(cnt%2==1) num[str[i-1]-'a']=1;
                cnt=1;
            }     
        for(int i=0;i<26;i++)
            if(num[i]==1) cout<<char(i+'a');   
                          cout<<endl;
    }
    return 0;
}

B.

题意:给你n串只含1.0字符串,问你经过任意交换后,最后能得到多少个回文串

思路:哎,本来想用贪心作的,就很麻烦,确实是境界低了,这原来就是个B题,仔细想一下,答案只能是n和n-1啊,n-1只能是n个字符串总为偶数并且1和0总书都是奇数,很简洁的一个题。

#include <iostream>
using namespace std;
int main(){
	int t;
	cin >> t;
	while(t--){
		string s;
		int n, num0 = 0, k = 0;
		cin >> n;
		for(int i = 1; i <= n; i++){
			cin >> s;
			int len = s.size();
			for(int j = 0; j < len; j++){
				if(s[j] == '0') num0++;
			}
			if(len % 2 == 1)	k++;			
		}
		if(k == 0 && num0 % 2 ==  1)
			cout << n-1 <<endl;
		else
			cout << n << endl;
	}
	return 0;
}

C.

题意:给一个数字,如果相邻的两个数奇偶性不同则可以交换,问你这个数字最后最小是多少。

思路:其实可以把整个数字看成多个“可交换区段”每一次改变交换区段就是由一个奇数或偶数交换后,就简单说,重新组合这个数字,而第一个数字的选择就只能是奇偶性第一次改变之前的区间中最小的,第二个数就是第二次改变前的区间,这样依次类推,这样实现起来也很简单,两个数组分别存储奇数和偶数,然后每次比较找小的就行了。

#include<iostream>
#include<vector>
using namespace std;
int main()
{
 int t;
 cin>>t;
 while(t--)
 {
   string s;
   int chong;
   cin>>s;
  vector<int>a,b;
  for(int i=0;i<s.length();i++)
  {
   int num=s[i]-'0';
   if(num%2)
    a.push_back(num);
   else 
    b.push_back(num);
  }
  int i,j;
  for(i=0,j=0;i<a.size()&&j<b.size();)
  {
   if(a[i]<b[j])
    cout<<a[i];i++;
   else 
    cout<<b[j];j++;
  }
  if(i<a.size())
   for(;i<a.size();i++) cout<<a[i];
  if(j<b.size())
   for(;j<b.size();j++) cout<<b[j];
  cout<<endl;
 }
}

D.

题意:你有N个员工,有K元钱,每个员工有工资范围,问怎么分配才能让工资中位数最大。

思路:本来想用贪心,最小工资排序,感觉还挺好的,但是后面的最大工资无法确定能大于中位数。于是看到了二分,我还真没想到要这样做,有点呆,check的时候就先把前面后面筛选出来,前面就取最少,后面就是也取最少,求sum,如果sum<=k就返回true就再看还能再花点钱吗

#include<iostream>
#include<vector>

using namespace std;
pair<int,int>a[200005];
int t,n,k,i,j;
bool check(int mid){
	int sum = 0;
	vector<pair<int, int>> v;
	for( i = 1; i <= n; i++){
		if(a[i].second<mid)
			sum += a[i].first;
		else
			v.push_back(a[i]);
	}
	ll len = v.size();
	if(len < n/2+1){
		return false;
	}
	sort(v.begin(), v.end());
	for (i = 0; i < (n/2+1); i++){
		sum += max(mid, v[len-i-1].first);
	}
	for( i = 0; i < len - (n/2+1); i++){
		sum += v[i].first;
	}
	if(sum <= k){
		return true;
	}
	else{
		return false;
	}
}	 
int main()
{
 cin>>t;
 while(t--)
 {
	 cin>>n>>k;
	 for(i=1;i<=n;i++)
		 cin>>a[i].first>>a[i].second;
	 int l=0,r=k;
	 while(l<=r){
		 int mid=(r+l)/2;
		 if(check(mid)) l=mid;
		 else           r=mid-1;
	 }
     cout<<r<<endl;
}

E1:

题意:有n个人,每个人有各自的mi 和 pi 如果有mi个人投你,那么他也会投你,如果不是mi个人投你,若让他投你,你就得花费pi 去贿赂他,问所有人投你要花费多少。

思路:好贪心,一个个向后枚举,从n到1进行选择,如果当前人数有i个得话,就可以全投了,pi的处理其实就好的多了,我们可以用贪心的办法解决,如果说 N - size < i,那么,我们的size一定是偏大了,我们就可以去把偏大的部分给买通了,这时候就可以用优先队列去找这size里面的最小p值即可。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
const int maxN = 2e5 + 7;
int N;
vector<int> vt[maxn];
using namespace std;
int main()
{
    int T,m,p; 
	cin>>T;
    while(T--)
    {
        scanf("%d", &N);
        for(int i=0; i<=N; i++) vt[i].clear();
        for(int i=1; i<=N; i++) { scanf("%d%d", &m, &p); vt[m].push_back(p); }
        priority_queue<int, vector<int>, greater<int>> Q;
        ll ans = 0;
        for(int i=N; i>=0; i--)
        {
            int len = (int)vt[i].size();
            for(int j=0; j<len; j++) Q.push(vt[i][j]);
            while(Q.size() > N - i) { ans += Q.top(); Q.pop(); }
        }
        printf("%lld\n", ans);
    }
    return 0;
}


 

### Codeforces 平台概述 Codeforces 是一个广受认可的在线编程竞赛平台,专注于算法竞技与程序设计能力提升[^1]。该平台由俄罗斯萨拉托夫州立大学的 Mike Mirzayanov 创建,自 2010 年上线以来已成为全球最具影响力的编程竞赛网站之一。 ### 编程竞赛机制 平台上定期举行名为 “Codeforces Round” 的定时竞赛,通常每两周一次,每次持续两小时左右。比赛采用分等级制度(Div. 1 和 Div. 2),根据参赛者当前 Rating 进行划分,确保公平竞争环境[^7]。近年来也推出了更灵活的比赛形式,如 Educational Rounds、Global Rounds 及 Team Contests,进一步丰富了赛事生态[^8]。 竞赛题目一般设置为 5 到 7 道不等,按难度递增标记为 A 至 G 级别。其中 A 题为基础模拟或贪心类问题,适合初学者;B/C 类常考察构造逻辑或多步推理;D/E 题则深入图论、动态规划、数论等领域;F/G 多用于高级技巧如复杂数据结构组合、概率期望推导等[^9]。 ```cpp // 示例:简单实现快速幂取模——常见于处理大指数运算场景 long long mod_pow(long long base, long long exp, long long mod) { long long result = 1; while (exp > 0) { if (exp & 1) result = (result * base) % mod; base = (base * base) % mod; exp >>= 1; } return result; } ``` ### 在线判题系统运作方式 提交代码后,系统会自动运行预设测试用例并返回反馈状态,包括 Accepted (AC)、Wrong Answer (WA)、Time Limit Exceeded (TLE)、Memory Limit Exceeded (MLE) 等结果码[^10]。评测基于 GNU C++ 编译器标准(常用 g++-x.x)、内存限制(通常 256MB)和时间约束(多数单测 ≤2 秒)。选手需注意输入输出效率优化,推荐使用 `scanf/printf` 或关闭同步流 (`ios::sync_with_stdio(false);`) 提升性能[^11]。 ### 算法题目特点与解题策略 Codeforces 的题目强调思维训练而非工程实践,典型考点覆盖: - **基础算法**:二分查找、前缀和、差分数组 - **经典结构**:栈、队列、优先队列、哈希表 - **高阶主题**:树状数组(BIT)、线段树、LCA 查询、网络流 部分难题融合多个知识点,例如 [Problem 1601F - Two Sorts] 要求结合排序理论与 ST 表技术,在离散化后的序列上维护区间最值映射关系,并考虑偏移量加减对位置索引的影响[^3]。 这类综合型挑战推动参与者掌握跨领域建模技能,同时也促进 STL 容器熟练运用与底层原理理解。 ### 社区影响与发展现状 截至近年统计数据显示,Codeforces 注册用户已突破百万级,来自超过 200 个国家和地区。其举办的 ICPC 训练营合作项目、Google Kick Start 前哨赛联动等活动显著提升了国际间青少年计算机教育互动频率[^12]。知名高校如 MIT、Stanford 将其作为选拔 ACM 国际队伍的重要参考依据之一。 活跃度方面,Top Rated 用户长期保持高强度刷题节奏,最高 Rating 曾达 4000+(tourist 保持历史纪录多年),反映出顶尖群体的技术沉淀强度[^13]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值