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

封闭图形个数(编程题) - 题解

题意解析:

8有两个封闭图形,0、4、6、9有一个封闭图形,1、2、3、5、7有一个封闭图形,按照一个数字的封闭图形个数为第一关键字,数字的大小为第二关键字排序,所以在本题中0到1从小到大排序的结果是1 2 3 5 7 0 4 6 9 8。

思路:

用结构体记录当前数字的大小和封闭图形数目,读入时用个函数算出来存到结构体中,重载一下<运算符sort一下就可以了。是不是很简单。

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 10;
//定义结构体
struct A
{
	//x指数字大小,y指当前数字封闭图形个数
	int x, y;
	//重载<运算符
	bool operator < (const A & u) const
	{
		//如果封闭图形个数相同,则比较数字大小
		if (y == u.y) return x < u.x;
		return y < u.y;
	}
}a[N];
//计算数字的封闭图形个数
int ttt(int x)
{
	int res = 0;
	//如果数字是0,直接返回1,因为0进不去while
	if (x == 0) return 1;
	//判断非0数字
	while (x)
	{
		//如果其中有8,加2,有0、4、6、9,加1
		if (x % 10 == 8) res += 2;
		else if (x % 10 == 0 || x % 10 == 4 || x % 10 == 6 || x % 10 == 9)
			res ++;
		//别忘了把最后一位去掉
		x /= 10;
	}
	return res;
}
void solve()
{
	int n; cin >> n;
	//读入并计算封闭图形数目
	for (int i = 1; i <= n; i ++ ) cin >> a[i].x, a[i].y = ttt(a[i].x);
	//排序
	sort(a + 1, a + 1 + n);
	//输出
	for (int i = 1; i <= n; i ++ ) cout << a[i].x << ' ';
}
signed main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int t = 1;
	// cin >> t;
	while (t --) solve();
	return 0;
}
2 回复 0 转发 1 喜欢 6 阅读
回复 (2)
默认 最新
露米 5 天前
思路写得很详细,代码的变量命名和注释也让人一目了然,是很用心的分享。🙂

用结构体配合重载运算符来解决多关键字排序,确实是个很经典且稳健的做法。这种把逻辑封装在结构体内部的思路,在以后处理更复杂的排序规则时会非常清晰。

另外,我注意到一个小细节:在开头的文字解析里,你提到“1、2、3、5、7有一个封闭图形”,不过对照你的 ttt 函数逻辑,这几个数字返回的应该是 0
个吧?可能是写解析的时候稍微手快了一下,修正这个小细节后就更严谨了。

这种用结构体配合重载运算符的做法真的很棒,代码的可读性很高。如果这道题的输入数字变得非常大,甚至超过了 long long 的范围,你觉得我们的处理方式会有什么变化吗?
0
露米 2026/2/16
思路写得很清晰呢,代码结构也很工整。🙂

特别注意到你在计算函数里给数字 0 做了单独处理,这个细节很贴心,能有效避免 while 循环漏掉 0 的情况。不过我留意到你在开头的题意解析里写到“1、2、3、5、7有一个封闭图形”,对照了一下你的代码逻辑,这几个数字对应的个数应该是 0 吧?可能是写解析的时候不小心笔误啦,稍微修正一下就完美了。

用结构体配合重载运算符来处理多关键字排序,是一个非常值得学习的编程习惯。如果以后遇到更复杂的排序规则,这个框架也会非常稳健。

想请教一下,如果这道题目要求输入的数字很大(比如超过了 long long 的范围),你觉得思路会有什么变化吗?
0