ICode9

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

CF EDU 105 C - 1D Sokoban

2022-05-23 12:31:07  阅读:181  来源: 互联网

标签:箱子 特殊 cntb int 位置 1D Sokoban include 105


C - 1D Sokoban

二分 + 找性质

可分正负的箱子分别讨论

本题的关键是发现一个重要的性质:因为推箱子这个过程会让被推到的箱子成为连续的一段,若想让在特殊位置的箱子最多,则这一段的终点一定要在特殊位置上(起点也可以, 这里的一定不是说不在特殊位置就取不到最优,而是在特殊位置上的某些情况一定可以取到最优,所以只考虑在特殊位置上的最大值就是全局的最大值)

证明思路:若结尾不是在特殊位置上,那么那把它移到最近的特殊位置上一定不会更劣

所以可以枚举每一个特殊位置,让连续一段箱子的末尾被推到这个点上,看这时的答案是多少

答案 = 这一段箱子覆盖的特殊位置 + 这一段箱子之后的点中,有多少箱子原来就在特殊位置上

第一项可二分求出,第二项可用前缀和求出

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <map>
using namespace std;
typedef long long ll;

const int N = 2e5 + 10;
int n, m;
int a[N], b[N], c[N], d[N], pre[N];
map<int, bool> mp;

int solve(int a[], int b[], int n, int m)
{
	if (n <= 0 || m <= 0)
		return 0;
	sort(a + 1, a + n + 1);
	sort(b + 1, b + m + 1);
	
	mp.clear();
	for (int i = 1; i <= n; i++)
		mp[a[i]] = true;
	for (int i = 1; i <= m; i++)
	{
		pre[i] = pre[i-1];
		if (mp.count(b[i]))
			pre[i]++;
	}
	int ans = 0;
	for (int i = 1; i <= m; i++)
	{
		int len = upper_bound(a + 1, a + n + 1, b[i]) - a - 1;
		int r = b[i], l = r - len + 1;
		int cnt = upper_bound(b + 1, b + m + 1, r) - lower_bound(b + 1, b + m + 1, l);
		cnt += pre[m] - pre[i];
		ans = max(ans, cnt);
	}
	return ans;
}

int main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	int T;
	cin >> T;
	while(T--)
	{
		cin >> n >> m;
		for (int i = 1; i <= n; i++)
			cin >> a[i];
		for (int i = 1; i <= m; i++)
			cin >> b[i];
		int ans = 0;
		int cnta = 0, cntb = 0;
		//正数
		for (int i = 1; i <= n; i++)
			if (a[i] > 0) c[++cnta] = a[i];
		for (int i = 1; i <= m; i++)
			if (b[i] > 0) d[++cntb] = b[i];
		ans = solve(c, d, cnta, cntb);
		//负数
		cnta = 0, cntb = 0;
		for (int i = 1; i <= n; i++)
			if (a[i] < 0) c[++cnta] = -a[i];
		for (int i = 1; i <= m; i++)
			if (b[i] < 0) d[++cntb] = -b[i];
		ans += solve(c, d, cnta, cntb);
		cout << ans << endl;
	}
	return 0;
}

标签:箱子,特殊,cntb,int,位置,1D,Sokoban,include,105
来源: https://www.cnblogs.com/hzy717zsy/p/16300772.html

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

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

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

ICode9版权所有