蓝桥杯暴力0到9恰好只出现一次问题

博客围绕0到9恰好只出现一次的问题展开,以“年龄的立方是4位数、4次方是6位数,这10个数字包含0到9且仅出现1次”的例题为例,探讨解题思路,指出不必用暴力或十层循环,将展示简单思路的解题代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大家一定经常遇到0到9恰好只出现一次的问题;
不妨先看一个例题

“年龄的立方是个4位数。年龄的4次方是个6位数。这10个数字正好包含了从0到9这10个数字,每个都恰好出现1次。”
请你推算一下,多少岁?

看到这道题首先想到的是什么解题思路?暴力?十层循环?

其实有很简单的思路;

看我的解题代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int arr[10] ;
int fun(int x){//判断是否出现两次
	while(x){
		arr[x%10]++;
		if(arr[x%10] > 1)
			return 0;
		x /= 10;
	} 
	return 1;
}

int main(int argc, char *argv[]) {
	int i, a, b;
	for(i=10; i<99; i++){
		memset(arr, 0, sizeof(arr));//这一步很关键,每次循环对arr数组初始化
		a = i*i*i;
		b = i*i*i*i;
		if(a>9999 || b>999999 || a<1000 || b<100000)
			continue;
		if(fun(a) && fun(b))//且的关系,每次运行都会改变arr数组里面的值
			printf("%d\n", i);
	} 	
}

仔细体会fun函数

你会有收获的

针对这一题其实还可以更简单:
https://blog.csdn.net/love_basketballer/article/details/79573704



**灵活运用**
例:https://blog.csdn.net/qq_27782065/article/details/50908267

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int arr[10];
void fun(int x){
	int i;
	while(x){
		arr[x%10]++;
		x /= 10;
	}
}
int pd(){
	int i;
	if(arr[0] != 0)
		return 0;
	for(i=1; i<10; i++)
		if(arr[i] != 1)
			return 0;
	return 1;
}
int main(int argc, char *argv[]) {
	int i, j, k, t;
	for(i=173; i<987; i++){
		for(j=123; j<987; j++){
			memset(arr, 0, sizeof(arr));
			t = i + j;
			if(t>999 || t < 100)
				continue;
			fun(i);
			fun(j); 
			fun(t);
			if(pd())
				printf("%d + %d = %d\n", i, j, t);
		}
	}
}
### 蓝桥杯 LITS 问题 C++ 实现与解题思路 #### 1. 题目背景分析 LITS 是一种逻辑谜题,目标是在网格中填充特定形状(L、I、T 和 S),使得每种形状恰好覆盖整个区域一次,并满足题目中的约束条件。这类问题通常涉及回溯法或深度优先搜索 (DFS),并结合剪枝优化来减少不必要的计算。 在蓝桥杯比赛中,此类问题的核心在于如何高效地表示状态以及设计合理的搜索策略[^1]。 #### 2. 数据结构的选择 为了描述 LITS 的解决方案,可以采用二维数组 `grid` 来存储当前的状态。其中: - 数字 `0` 表示未被占用的位置; - 字母 `&#39;L&#39;`, `&#39;I&#39;`, `&#39;T&#39;`, `&#39;S&#39;` 分别代表已放置的不同形状。 此外,还需要定义一个辅助函数用于检测某个位置是否合法,这可以通过检查相邻单元格是否存在冲突完成[^2]。 #### 3. 回溯算法框架 以下是基于 DFS 的基本回溯模板: ```cpp #include <iostream> #include <vector> using namespace std; const int N = 8; // 假设棋盘大小为N*N char grid[N][N]; // 存储当前布局 bool visited[N * N / 4]; // 记录哪些四连通块已被使用 // 判断当前位置(x,y)能否放入指定形状type bool isValid(int x, int y, char type); void solve(int pos){ if(pos >= N * N){ // 边界条件:如果已经填满则输出结果 for(int i=0;i<N;i++) cout<<grid[i]<<endl; exit(0); } int row=pos/N,col=pos%N; if(grid[row][col]!=&#39;.&#39;) return; // 已经有东西占据 for(auto &shape : {"L","I","T","S"}){ if(!visited[pos/4]){ if(isValid(row,col,*shape.begin())){ placeShape(row,col,*shape.begin()); // 放置该形状 visited[pos/4]=true; solve(pos+1); // 继续处理下一个 removeShape(row,col,*shape.begin()); // 撤销操作 visited[pos/4]=false; } } } } int main(){ memset(grid,&#39;.&#39;,sizeof(grid)); solve(0); } ``` 上述代码片段展示了核心部分——通过递归调用尝试所有可能的情况直到找到解答为止[^3]。 #### 4. 关键点说明 - **合法性验证**:每次尝试放置新图形之前都需要确认其不会违反任何规则。 - **去重机制**:为了避免重复计数相同配置下的不同排列方式,引入布尔型变量数组标记那些已经被利用过的区块组合。 - **性能改进措施**:尽管暴力枚举能够解决问题,但对于较大规模实例来说效率低下。因此建议加入启发式方法指导下一步决策方向或者提前终止明显无望分支以加速收敛过程[^4]。 #### 5. 结论 综上所述,在解决蓝桥杯上的 LITS 类型挑战时,推荐运用标准的回溯技术配合必要的预处理步骤构建优雅简洁而又高效的程序版本。同时也要注意平衡时间复杂度同空间需求之间的关系以便适应实际评测环境的要求[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值