1526B - I Hate 1111

题意

一个数字,判断是否能由11,111,1111,11111…组成

解析

数据量1e9,不能用背包解决,因此观察数据,发现11101=1111,111101=11111,因此x=a∗11+b∗101x=a*11+b*101x=a11+b101,我们只需要枚举其中一个,再判断另外一个是否能被整除即可。发现b=12的时候,x=a∗11+(11+1)∗101=>x=(a+101)∗11+101x=a*11+(11+1)*101=>x=(a+101)*11+101x=a11+(11+1)101=>x=(a+101)11+101,因此枚举12次b即可,不会超时。

代码

#include<iostream>
#include<vector>
using namespace std;
int main() {
	int t;
	cin >> t;
	while (t--) {
		int x;
		cin >> x;
		bool f = 0;
		for (int k = 0;(long long)k * 111 <= x;k++) {
			int j = x - (k * 111);
			if (j % 11 == 0) {
				f = 1;
				break;
			}
		}
		if (f) {
			cout << "YES" << endl;
		}
		else {
			cout << "NO" << endl;
		}
	}
}


<think>好的,用户现在问的是关于abs_diff = (s[i] - s[i-1]) >= 0 ? (s[i] - s[i-1]) : -(s[i] - s[i-1]);这句代码的意思。我需要先理解用户的问题,然后给出清晰的解释。 首先,用户之前已经询问过如何不用abs函数实现绝对值,我之前给出了使用条件运算符的示例。现在用户具体针对代码中的一行提问,可能是在阅读代码时对条件运算符的用法不太理解,或者想知道这段代码的具体执行逻辑。 接下来,我需要拆解这行代码。这行代码使用了三元条件运算符?:,结构是条件?结果1:结果2。当条件为真时,返回结果1,否则返回结果2。这里的条件是(s[i] - s[i-1]) >= 0,即计算两个字符的差值是否大于等于0。如果是的话,abs_diff就等于差值本身,否则取相反数,这样就能得到绝对值。 用户可能对三元运算符不熟悉,或者不理解为什么这样可以实现绝对值。需要详细解释每个部分的作用。同时,用户可能没有注意到重复计算的问题,比如这里两次计算了s[i]-s[i-1],这可能会影响效率,尤其是如果s是复杂表达式的话。我之前给出的示例中,是先将差值保存到diff变量中,避免了重复计算,所以这里需要指出两种方式的区别,并推荐更优的做法。 另外,用户可能是在学习C语言的基础知识,特别是条件运算符的使用,或者绝对值的手动实现方法。需要确保解释清晰,步骤明确,避免使用过于专业的术语,让初学者也能理解。 可能还需要举例说明,比如具体的数值代入,让用户看到当差值为正、负或零时,结果如何变化。例如,差值为3时,直接返回3;差值为-3时,返回3;差值为0时返回0,这样就得到了绝对值。 另外,用户可能想知道这行代码和标准库中的abs函数有什么区别,或者为什么选择这种方式。需要说明这种方法的适用性,比如适用于所有整数类型,而abs函数可能有不同的版本(如abs、labs等),或者用户被限制不能使用库函数时的替代方案。 最后,总结代码的作用,强调其实现的是绝对值计算,并指出潜在的问题,比如重复计算可能导致的效率问题,建议用户使用变量存储中间结果以提高代码效率和可读性。</think>以下是这行代码的详细解析: --- ### **代码结构** ```c abs_diff = (s[i] - s[i-1]) >= 0 ? (s[i] - s[i-1]) : -(s[i] - s[i-1]); ``` --- ### **分步解释** 1. **计算差值** `s[i] - s[i-1]`:计算字符数组中**当前字符**与**前一个字符**的 ASCII 码差值。 - 例如:`s = "ab"`,则 `s[1]-s[0] = 'b'-'a' = 1` 2. **判断差值符号** `(差值) >= 0 ? ... : ...`:使用**三元条件运算符**判断差值的正负: - 若 $\text{差值} \geq 0$,直接取原值 - 若 $\text{差值} < 0$,取其相反数(即 `-差值`) 3. **等价逻辑** 这行代码等价于: ```c if (s[i] - s[i-1] >= 0) { abs_diff = s[i] - s[i-1]; } else { abs_diff = -(s[i] - s[i-1]); } ``` --- ### **实例演示** 假设字符串为 `"hate"`(ASCII 值:`h=104`, `a=97`, `t=116`, `e=101`): | 字符对 | 差值计算 | 逻辑判断 | 结果 | |--------|----------|----------|------| | `a-h` | 97-104 = -7 | -7 < 0 → 取 `-(-7)` | 7 | | `t-a` | 116-97 = 19 | 19 ≥ 0 → 直接保留 | 19 | | `e-t` | 101-116 = -15 | -15 < 0 → 取 `-(-15)` | 15 | --- ### **潜在问题与优化** 1. **重复计算** 代码中重复计算了 `s[i] - s[i-1]` **三次**,可通过**中间变量**优化: ```c int diff = s[i] - s[i-1]; abs_diff = (diff >= 0) ? diff : -diff; ``` - 优化后仅计算一次差值,效率更高 2. **可读性** 三元运算符虽简洁,但长表达式可能降低可读性,建议添加注释: ```c abs_diff = (diff >= 0) ? diff : -diff; // 计算绝对值 ``` --- ### **总结** 这行代码的作用是: **计算两个相邻字符的 ASCII 码差值的绝对值**,等同于数学公式: $$ \text{abs\_diff} = |s[i] - s[i-1]| $$ 适用于需要**避免使用库函数**或**自定义绝对值逻辑**的场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值