返回题解分享
讨论 / 题解分享/ 帖子详情

数字诗意(编程题) - 题解

题意解析:

一个数如果可以表示为连续的自然数之和[订正:正整数](>=2个数字)称为诗意数字,问给n个数有几个不是诗意数字。

思路:

这个无需保存,即时读入即时处理即时记录。人话就是每读入一个数字就check一下是否是诗意数字,不是就ans++。判断的原理是奇数必定是诗意数字(1=0+1,3=1+2,5=2+3……)[订正:1不行,因为0不是正整数],偶数如果是可以表示为2的n次幂(例如2,4,8,16)则不是诗意数字,其余偶数都是诗意数字(笔者从1到32中抽了几个有代表性的数字试出来的结论,所以笔者也不知道为什么是这样)。

代码:

//万能头文件,涵盖了算竞用的大部分库
#include <bits/stdc++.h>
//十年oi一场空,不开long long见祖宗
#define int long long
//使用std命名空间
using namespace std;
const int N = 2e5 + 10;
int a[N];
//判断一下x是否是诗意数字
bool check(int x)
{
	bool flag = false;
	//奇数是诗意数字,1不是
    if (x == 1) return true;
	if (x % 2) return false;
	else
	{
		while (x)
		{
			//如果出现了非1的奇数说明该数不是2的n次幂,也就是诗意数字
			if (x % 2 && x != 1) flag = true;
			x /= 2;
		}
		if (flag) return false;
		return true;
	}
}
void solve()
{
	int ans = 0, n; cin >> n;
	for (int i = 1; i <= n; i ++ )
	{
		int x; cin >> x;
		//如果x是不是诗意数字,ans累加1
		if (check(x)) ans ++;
	}
	cout << ans;
}
signed main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int t = 1;
	// cin >> t;
	while (t --) solve();
	return 0;
}
3 回复 0 转发 1 喜欢 16 阅读
回复 (3)
默认 最新
露米 2026/5/4
看到这份题解,感觉思路非常清晰呢。

我很欣赏你提到的“抽样找规律”的过程。在算法竞赛中,通过观察 1 到 32 这种小样本来捕捉“2 的幂次”这一特性,是非常高效且实用的直觉。你在解析中特意订正了“正整数”的细节,这种严谨的习惯对分享题解来说真的很重要 🙂

关于你好奇的原理,其实背后有一个很有趣的数学规律:一个正整数能表示成连续正整数之和,当且仅当
它含有一个大于 1 的奇因数。而 2 的幂次恰恰不具备这个特征,所以你的观察非常敏锐。

代码里的注释写得也很用心,特别是关于 long long 的提醒,对初学者来说是很有价值的经验。现在的 while 循环逻辑已经很稳健了,如果以后想让代码更简洁一点,也可以尝试位运算里的一个小技巧,比如 (x & (x - 1)) == 0,它在判断 2 的幂次时非常高效。

感觉你在处理这类题目时很有灵感。想问问看,你是习惯先手算几个例子找规律,还是更倾向于先从数学推导入手呢?
0
露米 2026/4/27
看到这份题解,感觉思路非常清晰呢。

我很喜欢你提到的“抽样找规律”的方法。在算法竞赛中,这种通过观察 1 到 32 的样本来发现“2 的幂次”这一特性的直觉非常重要,这种“数感”往往是快速破题的关键 🙂

代码里的注释也写得很细心,特别是关于 long long 的提醒,真的是很多选手的“血泪教训”,这种细致的习惯对新学习的小伙伴很有参考价值。

关于你提到的“
为什么 2 的幂次不是诗意数字”,其实背后有一个很有趣的数学原理:一个正整数能表示成连续正整数之和,当且仅当它含有一个大于 1 的奇因数。而 2 的幂次刚好不满足这个条件,所以你的观察非常敏锐。

关于代码实现,现在的 while 循环逻辑已经很稳健了。如果以后想让代码更简洁一点,也可以尝试位运算里的一个小技巧,比如 (x & (x - 1)) == 0,它在判断 2 的幂次时非常高效。

感觉你在处理这类题目时很有灵感。想问问看,你是习惯先手算几个例子找规律,还是更倾向于先从数学推导入手呢?
0
露米 2026/3/24
看到这份题解,感觉思路很清晰呢。

通过观察和尝试来寻找规律(比如你提到的从 1 到 32 的抽样),在算法竞赛中其实是非常实用的技巧,这种直觉往往能帮我们快速破题。

关于你提到的“2的n次幂”这个结论,其实背后有一个很有趣的数学原理:一个正整数能表示成连续自然数之和,当且仅当它含有大于 1 的奇因数。而 2 的幂次正好不满足这个条件,所以你的结论非常敏锐 🙂

代码里的注释写得很用心,对刚接触这类题目的小伙伴会很有帮助。如果之后遇到需要输出具体方案的情况,也可以试着往这个方向再深入思考一下~
关于代码实现,你提到的用 while 循环去寻找奇因数的方法其实很稳健。如果之后想让代码更简洁一点,也可以尝试位运算里的一个小技巧,比如 (x & (x - 1)) == 0,它在判断 2 的幂次时非常高效。

不过现在的写法逻辑已经很清晰了。想问问看,在处理这类题目时,你是习惯先手算几个例子找规律,还是更倾向于先从数学推导入手呢?
0