Codeforces Global Round 16

A. Median Maximization

这道题就是一简单的思维题,直接放代码

#include <iostream>
#include <cstdio>
using namespace std;

const int N = 1e4 + 10;

int main()
{
	int T;
	cin >> T;
	while(T--)
	{
		int n, s; 
		scanf("%d%d", &n, &s);
		
		if(n % 2 == 0)
		{
			int t = n / 2;
			cout << s / (n - t + 1) << endl;
		}
		else
		{
			int t = n / 2 + 1;
			cout << s / (n - t + 1) << endl;
		}
	}
	
	return 0;
} 

B. MIN-MEX Cut

b题一开始理解错了,以为字串是可以不连续的,
字串:在字符串取出一块连续的
子序列:在字符串中顺序取出,但是可以不连续
那么接下来就可做了,首先我们知道不管怎么样,答案是不会超过2的,所以我们可以贪心的枚举该字符串,然后判断是否超过2,
参考代码

#include <iostream>
using namespace std;

int main()
{
	int T;
	cin >> T;
	
	while(T--)
	{
		string s;
		cin >> s;
		
		int ans = 0;
		for(int i = 0; i < s.size() - 1; i++)
		{
			if(s[i] != s[i + 1])
			{
				if(s[i] == '0') ans += 1;
				else if(s[i] == '1') ans += 0;
			}
		}
		
		if(s[s.size() - 1] == '0') ans += 1;
		else ans += 0; 
		
		if(ans >= 2) cout << "2" << endl;
		else cout << ans << endl;
	}
	return 0;
}

C. MAX-MEX Cut

这题在比赛是没做出来,不知道为什么第8个测试点超时了,早上起来补题时发现,忘记我这个做法如果全为1时,时间复度为 O(n ^ 2),然后优化了一下,发现就过了,好可惜呀
参考代码

#include <iostream>
using namespace std;

int main()
{
	int T;
	cin >> T;
	
	while(T--)
	{
		int n;
		string s1, s2;
		cin >> n >> s1 >> s2;
		
		int ans = 0;
		for(int i = 0; i < n; i++)
		{
			if(s1[i] != s2[i]) ans += 2;
			else
			{
				if(s1[i] == '1')
				{
					int j;
					for(j = i + 1; j < n; j++)
					{
						if(s1[j] == s2[j] && s1[j] == '0')
						{
							ans += 2;
							i = j;
							break;
						}
						if(s1[j] != s2[j])
						{
							i = j - 1;
							break;
						}
					}
					if(j == n) break;
				}
				
				
				else
				{
					if(s1[i + 1] == s2[i + 1] && s1[i + 1] == '1')
					{
						ans += 2;
						i++;
					}
					else ans += 1;
				}	
			}
		}
		
		cout << ans << endl;
	} 
	return 0;

但出于代码的简洁性,下面为官方代码:

#include <iostream>
#include <algorithm>
using namespace std;

int slove(string s)
{
	int sum = count(s.begin(), s.end(), '0');
	
	bool flag1 = false, flag2 = false;
	for(int i = 0; i < s.size(); i++)
	{
		if(s[i] == '1') flag1 = true;
		if(s[i] == '0') flag2 = true;
		
		if(flag1 && flag2) 
		{
			sum++;
			flag1 = flag2 = false;
		}
	}
	
	return sum;
}

int main()
{
	int T;
	cin >> T;
	
	while(T--)
	{
		int n;
		string a, b, s;
		cin >> n >> a >> b;
		
		int ans = 0;
		for(int i = 0; i < n; i++)
		{
			if(a[i] != b[i])
			{
				ans += 2 + slove(s);
				s = "";
			}
			else s += a[i]; 
		}
		
		cout << ans + slove(s) << endl;
	}
	return 0; 
} 

D1. Seating Arrangements (easy version)

这题,没什么好说,暴力就完事
参考代码

#include <iostream>
using namespace std;

const int N = 310;

int a[N][N];

int main()
{
	int T;
	cin >> T;
	
	while(T--)
	{
		int n, m;
		cin >> n >> m;
		
		for(int i = 1; i <= n; i++)
			for(int j = 1; j <= m; j++) cin >> a[i][j];
			
		int ans = 0;
		for(int i = 1; i <= n; i++)
		{
			for(int j = 1; j <= m; j++)
			{
				int t = 0;
				for(int k = 1; k < j; k++)
				{
					if(a[i][k] < a[i][j]) t++;
				}
				ans += t;
			}
		}
		
		cout << ans << endl;
	}
	
	return 0;
}

D2. Seating Arrangements (hard version)

这题是D1的困难版,当时做这题时,已经很晚了,然后看了下,发现时间可能不够(还有20分钟结束),然后就去睡觉了
然后早上起来补题,发现好像不是特别难,就是排序的问题,
先排一次序,确定这些人怎么安排,在根据下标排一次序,累加答案,当然有些小细节需要注意一下,就是第一次排序时,但2个数相等时,下标小的在前面,这样才能确保答案最小

#include <iostream>
#include <algorithm>
using namespace std;

const int N = 100010;

struct stu
{
	int w, id;
}a[N];

bool cmp1(stu x, stu y)
{
	if(x.w == y.w) return x.id < y.id;
	return x.w < y.w;
}

bool cmp2(stu x ,stu y)
{
	return x.id < y.id;
}

int main()
{
	int T;
	cin >> T;
	
	while(T--)
	{
		int n, m;
		cin >> n >> m;
		for(int i = 1; i <= n * m; i++) cin >> a[i].w, a[i].id = i;
		
		sort(a + 1, a + n * m + 1, cmp1);
		
		int ans = 0;
		for(int i = 0; i < n; i++)
		{
			int t = 1 + i * m;
			sort(a + t, a + m + t, cmp2);
			for(int j = t; j <= (i + 1) * m; j++)
			{
				for(int k = t; k < j; k++)
					if(a[k].w < a[j].w) ans++;
			}
		}
		
		cout << ans << endl;
	}
	return 0;
} 

总结:

总的来说这场cf好像并不是特别的难,但是需要手速(hh),感觉自己对有些概念和库函数还不是非常熟悉,所以以后得更加努力的写题,看课。

count()库函数:
count(a.begin(), a.end(), s); s为需要统计的数或字符

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值