Codeforces Round 984 (Div. 3)——题解

A Quintomania

思路:暴力

B Startup

题意: 给你n个货架 和m种品牌的饮料
每个货架上只能放一种牌子,问最大利润是多少

思路:贪心 建立一个vector p(m)

以品牌号为数组下标,将相同的牌子累加,最后sort降序排序,加上前n个即可

注意点: 货架数和饮料种类数找最小值 当最后的相加次数 例如 1000 1   1 10000 的情况

AC 代码

#include <iostream>
#include <algorithm>
#include <math.h>
#include <vector>
using namespace std;


int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		long long n, k,b,c;
	     
		
		cin >> n >> k;
		n=min(n, k);
		vector<int>p(k);

		for (int i = 0; i < k; i++)
		{
			cin >> b >> c;
			b--;
			p[b] += c;
		}

		sort(p.rbegin(),p.rend()); //排好倒着输出 从而降序排序
		long long ans = 0;
		for (int i = 0; i < n; i++)
		{
			ans += p[i];
		}

	

		cout << ans << endl;
	}

	return 0;
}

C Anya and 1100

题意: 指定一个数组位置q,将它换成u,然后查看数组中是否存在1100字符串,
如果有就输出YES,否则输出NO

数据量很大 2⋅1E5 最初想法是暴力遍历所有数据,找1100,果不其然超时了
学习其他人的思路后,最后才发现还是想法太简单。

1.不需要每次都遍历所有数据,只需要查看q-3到q+3这段范围的改变前后的1100增减情况
加上cnt的总和只要大于0即可


优点:极大减少了查询次数,而cnt我们也只用每次接受字符串时预处理一次即可 

2.确定查询的左右范围

for(int i=max(0,q-3);i<=min(q,len-4),i++)

max(0,q-3) 确定左边的开始位置
min(q,len-4) 确定右边的结束位置 
完美的解决了边界问题

3.优化
if(s[q]!=u)
{
  执行计算;
}
如果输入的u等于了s[q]那结果不会被影响,就没有计算的必要

alt

AC 代码

#include <iostream>
#include <algorithm>
#include <math.h>
#include <string>
using namespace std;

int main()
{

    int t;

    cin >> t;
    while (t--)
	{

		string s;
		int n, cnt = 0;
		int  len=0;
		cin >> s;
		cin >> n;

		len = s.length();

		for (int i = 0; i < len - 3; i++)
		{
			cnt += s.substr(i, 4) == "1100"; //预处理1100的个数

		}
			while (n--)
			{
		     	int  q;
				char u;
				cin >> q >> u;
				q--;	
				if (s[q] != u)
				{
					for (int i = max(0, q - 3); i <= min(q, (len - 4)); i++)
					{
						cnt -= s.substr(i, 4) == "1100";
					}
					s[q] = u;
					for (int i = max(0, q - 3); i <= min(q, (len - 4)); i++)
					{
						cnt += s.substr(i, 4) == "1100";
					}
				}
				if (cnt)
				{
					cout << "YES" << endl;
				}
				else
				{
					cout << "NO" << endl;
				}
	

			}

	}


	return 0;
}

D.I Love 1543

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务