第七届蓝桥决赛凑平方数

把0~9这10个数字,分成多个组,每个组恰好是一个平方数,这是能够办到的。
比如:0, 36, 5948721
再比如:
1098524736
1, 25, 6390784
0, 4, 289, 15376
等等...
注意,0可以作为独立的数字,但不能作为多位数字的开始。
分组时,必须用完所有的数字,不能重复,不能遗漏。
如果不计较小组内数据的先后顺序,请问有多少种不同的分组方案?

注意:需要提交的是一个整数,不要填写多余内容。

思路:
(1)首先将合格的平方数以字符串的形式存入数组ans 
(2) void dfs(int start,string s); start是ans开始的位置 s是已经选择的平方数连接构成的字符串
 例如 ans[] = {"0","1","4","9","16","25","36","49",...}
 现在start = 0 ;s = ""; 
 我们选择了ans[0] = "0" s = "" + "0" = "0"; start = 0+1;
 然后我们选择ans[1] = "1";s = "0"+"1" = "01"(s是所有的选择的字符串进行连接);start = 2(表示下一次需要从下标为2开始选);

 如果某一次 s 的长度为10 而且没有重复的字符,那么sum++; 

注:这是同学给我讲完之后我才明白的,所以文章类型选择翻译,感谢同学给我讲解。

#include<iostream>
#include<string>
using namespace std; 
int total = 0,sum = 0 ;//total是有多少个合格的平方数 sum 是一共多少种组合
string ans[100000];//用来存放合格的平方数的字符串形式 
bool check(string s);//用来检测s中是否有重复的字符
string toss (long long n);//将数字n转化为字符串
void init();//将全部合适的平方数存入数组
void dfs(int start,string s);
int main()
{
	init();
	string s = "";
	dfs(0,s);
	cout<<sum<<endl;
	return 0;
}
void dfs(int start,string s) 
{
	if(s.size()>10 || !check(s)){
		return;
	}
	else if(s.size()==10 && check(s)){
		sum ++;
		return;
	}
	else{
		for(int i=start ;i<total;i++){ 
			dfs(i+1,s+ans[i]);
		}
	}
}
bool check(string s)
{
	int u[10] = {0};
	int i,j;
	for(i=0;i<s.size();i++){
		u[s[i]-'0']++;
		if(u[s[i]-'0']>1){
			return false;
		}
	} 
	return true;
}
string toss (long long n)
{
	string s = "";
	do{
		char c[] = {n%10+'0','\0'};//因为字符串之间可以连接 c数组相当于一个字符串 
		s = c + s;
		n/=10;
	}while(n!=0);
	return s;	
} 
void init()
{
	long long i,j;
	string s;
	for(i=0;i<1e5+10;i++){//如果i是int型的话就会出错,我也不太清楚为什么 
		j = i*i;
		s = toss(j);
		/*---------如果这个平方数没有重复的数字的话----------- */
		if(check(s)){
			ans[total++] = s;
		}
	}
}

### 关于第九届蓝桥杯单片机比赛中与数码管相关的资料 虽然当前提供的引用并未直接提及第九届蓝桥杯单片机比赛中的具体数码管相关内容,但从其他几届的比赛情况可以推测出一些通用的设计思路和技术要点。以下是基于已有经验以及相关技术背景整理的内容。 #### 数码管显示原理 数码管是一种常见的七段或八段显示器,通过控制不同的段点亮组合来显示数字或其他字符。在嵌入式系统中,通常采用GPIO口或者专用芯片(如74HC595)驱动数码管。对于动态扫描方式,多个数码管可以通过分时刷新的方式共享相同的段选线,从而减少硬件资源占用[^1]。 #### 示例代码解析 以下是一个简单的静态数码管显示程序示例: ```c #include <reg52.h> sbit D0 = P2^0; // 定义数码管各段对应的IO端口 sbit D1 = P2^1; sbit D2 = P2^2; sbit D3 = P2^3; sbit D4 = P2^4; sbit D5 = P2^5; sbit D6 = P2^6; unsigned char code table[] = {0xC0, 0xF9, 0xA4, 0xB0}; // 对应0~3的字型码 void main() { unsigned char i = 0; while (1) { D0 = table[i & 0x03]; // 显示i%4的结果 delay_ms(500); // 延时函数 i++; } } ``` 上述代码展示了如何通过查表法设置不同数值到数码管上显示,并实现了循环计数功能。其中`table[]`数组存储了对应数字的字形编码[^2]。 #### 动态扫描方法简介 当需要驱动多位数码管时,推荐使用动态扫描技术以节省I/O资源并提高效率。其核心思想在于快速切换每一位数码管的数据输入状态,在视觉暂留效应下形成连续稳定的图像效果[^3]。 #### 注意事项 - **初始化配置**:确保所有涉及的外设均已完成必要的初始化操作。 - **延时处理**:适当调整延迟时间以免影响最终呈现质量。 - **抗干扰措施**:考虑到实际环境中可能存在电磁噪声等因素的影响,建议加入软件去抖动逻辑或是硬件滤波电路设计。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值