首页 > 其他分享 >从CF1901C学习除二向下取整的思路

从CF1901C学习除二向下取整的思路

时间:2024-01-21 21:45:03浏览次数:43  
标签:除二 奇数 dfrac 偶数 序列 取整 CF1901C 操作

https://codeforces.com/problemset/problem/1901/C

我发现对于向下取整向上取整的题目(特指除二),没有一些常见的思路积累。

Description

给定一个长度为 \(n\) 的序列 \(\{a_n\}\)。每次操作你需要选择一个整数 \(x\) 并将所有 \(a_i\) 替换为 \(\lfloor \frac {a_i + x}2 \rfloor\)。求至少多少次操作后能将所有 \(a_i\) 变相同。

若最少次数小于等于 \(n\),输出操作次数和每次操作所选择的 \(x\)。否则仅输出操作次数。

\(1 \le n \le 2 \times 10^5\),\(0 \le a_i \le 10^9\)。

Solution

可以观察到,每次操作后,数字的相对大小关系不会发生改变。

例如 \(a = \{4, 2, 5\}\),\(x = 3\),那么操作后的 \(a' = \{3, 2, 4\}\)。可以发现 \(a_3\) 和 \(a'_3\) 分别都是两个序列的最大值,\(a_2\) 和 \(a'_2\) 都是两个序列的最小值。

那么就启发我们不用同时维护原序列中的所有值,只需要维护序列中的最大值和最小值。当这两个值相等时,就代表序列中所有的数都相同了。

那么问题就被转化成了这样:

给定两个整数 \(a, b(a > b)\)。每次操作你需要选择一个整数 \(x\) 并将 \(a \gets \lfloor \frac {a + x}2 \rfloor\),\(b \gets \lfloor \frac {b + x}2 \rfloor\)。求至少多少次操作后 \(a = b\)。

每次操作我们肯定是希望利用下取整这个优秀性质来让 \(a\) 尽量接近 \(b\),也就是想让操作后 \(a - b\) 尽量小。那么我们可以直接分讨:

然后就解决了。用 vector 记录答案即可。

Code

void solve()
{
	cin >> n;
	a = 0, b = 2e9;
	for (int i = 1; i <= n; ++ i )
	{
		cin >> x;
		a = max(a, x);
		b = min(b, x);
	}
	
	vector<int> res;
	while (a != b)
	{
		if (a % 2 == 0 && b % 2 == 0) x = rand();
		else if (a % 2 == 1 && b % 2 == 1) x = rand();
		else if (a % 2 == 0 && b % 2 == 1) x = rand() * 2 + 1;
		else x = rand() * 2;
		a = (a + x) / 2;
		b = (b + x) / 2;
		res.push_back(x);
	}
	
	cout << res.size() << '\n';
	if (res.size() <= n)
	{
		for (auto i : res) cout << i << ' ';
		if (res.size()) puts("");
	}
	
	return;
}

题解的四个超链接很重要,对于除以二的向下取整的值,可以直接把奇数的转成减一除二

\(a\) 为偶数,\(b\) 为偶数

令 \(\Delta\) 为操作后 \(a\) 与 \(b\) 的差。

  • 若选择的 \(x\) 为偶数: \(a' = \dfrac {a + x} 2\),\(b' = \dfrac {b + x}2\),\(\Delta = \dfrac {a - b} 2\)。 -
  • 若选择的 \(x\) 为奇数: \(a' = \dfrac {a + x - 1} 2\),\(b' = \dfrac {b + x - 1} 2\),\(\Delta = \dfrac {a - b}2\)。
  • 可以发现,无论 \(x\) 怎样取值,两数差一定为 \(\dfrac {a - b}2\)。因此 \(x\) 任意取值。

标签:除二,奇数,dfrac,偶数,序列,取整,CF1901C,操作
From: https://www.cnblogs.com/kdlyh/p/17978428

相关文章

  • 30_删除二叉搜索树中的节点
    450.删除二叉搜索树中的节点给定一个二叉搜索树的根节点root和一个值key,删除二叉搜索树中的key对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。一般来说,删除节点可分为两个步骤:首先找到需要删除的节点;如果找到了,删除它。示例1:......
  • 代码随想录 day22 二叉搜索树的最近公共祖先 二叉搜索树中的插入操作 删除二叉搜索树
    二叉搜索树的最近公共祖先这题跟之前的不一样可以利用二叉搜索树有序的特点有序就说明可以根据节点的值与pq的关系判断应该往左边搜索还是右边搜索这题显然是不需要遍历整棵树的所以是写的遍历边的写法遍历树需要用变量接受二叉搜索树中的插入操作一开始还以为要遍历......
  • python 浮点数 round 舍一法 向零取整 df 数组 Series 三种数据类型实现
    介绍:python的round函数,默认进行四舍五入,我需要将3.45保留一位小数,3.4 一、一般格式使用Python的内置函数 math.floor() 来向下取整到指定的小数位数。例如,如果你想保留小数点后一位并向下取整,可以这样做:importmathnum=3.45rounded_num=math.floor(num*10)/......
  • 【C语言】浮点数取整
    向下取整1. 强制类型转换floatf=1.5;inta;a=(int)f;2.高斯函数doublefloor(doublea)floatf=1.5;inta;a=floor(f);向上取整1.ceil函数doubleceil(doublea)floatf=1.5;inta;a=ceil(f); 2. 强制类型转换+四舍五入floatf=......
  • SQL中的取整函数
    SQL中的取整函数FLOOR、ROUND、CEIL、TRUNC、SIGN(2009-12-2917:13:12)标签:整函数fromabs小数点绝对值教育分类:02.数据处理1trunc(value,precision)按精度(precision)截取某个数字,不进行舍入操作。2round(value,precision)根据给定的精度(precision)输入......
  • python删除二维数组的某一行某一列
    Python删除二维数组的某一行某一列1.简介在Python中,二维数组可以通过列表嵌套的方式实现。删除二维数组的某一行或某一列可以使用Python内置的列表操作方法来实现。在本篇文章中,我将向你介绍如何使用Python来删除二维数组的某一行或某一列。2.删除二维数组的某一行删除二维......
  • 如何强制进行浮点数除法?除法总是向下取整为0?
    内容来自DOChttps://q.houxu6.top/?s=如何强制进行浮点数除法?除法总是向下取整为0?我有两个整数值a和b,但需要它们的浮点数比率。我知道a<b,我想计算a/b,所以如果我使用整数除法,我总是会得到一个余数为a的0。在Python2中,如何强制将c变成浮点数?c=a/b在......
  • JS 小数取整的几种方式
    1、Math.ceil()方法:向上取整,不管小数部分是多少,整数部分值都+1Math.ceil(3/2)输出:22、Math.floor()方法:向下取整,不管小数部分是多少,整数部分值都不变,只取整数部分Math.floor(3/2)输出:13、Math.round()方法:四舍五入取整Math.round(3/2)输出:24、parseInt()方法:抛去小数部分,不......
  • 第十八篇 - el-select获取整个对象值
    参考链接:https://blog.csdn.net/qq_41885295/article/details/121956909常规el-select时的用法是这样的<el-form-itemlabel="Project"style="flex:1":rules="[{required:true,message:'',trigger:'blur'},]">&......
  • Java正整数除法向上取整
    1、简介在今天刷每日一题的时候看到的,感觉和以前自己写的向上取证的写法比起来好很多,在此记录。来源:1921.消灭怪物的最大数量-力扣(LeetCode)2、内容仅仅在正整数除法,三种都可用1、Math.ceil()2、x/y+(x%y==0?0:1)3、(x-1)/y+1classSolution{publicstaticvoidma......