ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF922D Robot Vacuum Cleaner

2020-12-02 11:35:29  阅读:148  来源: 互联网

标签:std Cleaner int S2 CF922D Robot Node Str include


题目分析

观察数据范围 \(n \leq 10^5\), 还有 "任意顺序连接" 及 "最大化" 的要求, 自然想到了做法 : 邻项交换

考虑相邻的两个位置 \(i\) 与 \(j = i + 1\), 他们的相对顺序不会影响 \([1, i - 1]\) 及 \([j + 1, n]\) 这些位置的答案. 所以只需要考虑 \(i, j\) 之间的贡献.

  1. 当 \(i\) 在 \(j\) 之前, \(i, j\) 之间的贡献应为 : \(countS ( \ Str(i) \ ) * countH ( \ Str(j) \ )\)
  2. 当 \(j\) 在 \(i\) 之前, \(i, j\) 之间的贡献应为 : \(countS ( \ Str(j) \ ) * countH ( \ Str(i) \ )\)

只需比较以上两式之间的大小就能确定 \(i, j\) 之间的相对顺序. 由于这满足严格弱序, 可以扩展到全局.

把式子写成 \(Cmp()\) 就能用 \(std::sort()\) 以 \(O(nlogn)\) 求出最优的排列顺序.

统计答案非常简单, \(O(n)\) 扫一遍即可.

细节请看代码.

代码实现

#include <cstdio>
#include <string>
#include <iostream>
#include <algorithm>

const int N = 1e5;

int n;
std::string Str[N + 5];

struct Node { int S1, S2, Id; } Q[N + 5];

bool Cmp (Node, Node);

int main() {
	std::ios::sync_with_stdio (false);

	std::cin >> n;
	for (int i = 1; i <= n; ++i) {
		std::cin >> Str[i];
		int Len = Str[i].length();
		for (int j = 0; j < Len; ++j)
			Q[i].S1 += (Str[i][j] == 's'), Q[i].S2 += (Str[i][j] == 'h');
		Q[i].Id = i;
	
	} std::sort (Q + 1, Q + 1 + n, Cmp);
	
	auto NowS = 0ll, Ans = 0ll;
	for (int i = 1; i <= n; ++i) {
		int Len = Str[Q[i].Id].length();
		for (int j = 0; j < Len; ++j) {
			char tap = Str[Q[i].Id][j];
			if (tap == 's') ++NowS;
			else Ans += NowS;
		}
	} printf ("%lld\n", Ans);
	return 0;

} bool Cmp (Node X, Node Y) {
	return 1LL * X.S1 * Y.S2 > 1LL * Y.S1 * X.S2;
}

标签:std,Cleaner,int,S2,CF922D,Robot,Node,Str,include
来源: https://www.cnblogs.com/Rothen/p/14072718.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有