蓝桥杯寒假训练二1005 DFS以及三重循环的问题出在memset不能对1进行赋值

本文通过两种不同的编程方法解决了一道数学谜题:寻找符合特定条件的四位数ABCD,使得(ABCD-EFGH)*XY=900。利用深度优先搜索(DFS)和三重循环遍历的方法,文章提供了代码实现并最终找到符合条件的数字。

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

题目大意:

请看下面的算式:
(ABCD - EFGH) * XY = 900
每个字母代表一个0~9的数字,不同字母代表不同数字,首位不能为0。
比如,(5012 - 4987) * 36 就是一个解。
请找到另一个解,并提交该解中 ABCD 所代表的整数。

注意:只提交 ABCD 所代表的整数,不要写其它附加内容,比如:说明性的文字。

经典DFS

#include<iostream>
using namespace std;
int a[10]={0};
int b[10]={0};
int first=0,second=0,third=0; 
void dfs(int m)
{
	if(m==10)
	{
		first=a[0]*1000+a[1]*100+a[2]*10+a[3];
		second=a[4]*1000+a[5]*100+a[6]*10+a[7];
		third=a[8]*10+a[9];
		if((first-second)*third==900&&first>=1000&&second>=1000&&third>=10)
		{
			cout<<first<<endl;
			return;
		}
	}

	for(int i=0;i<10;i++)
	{
		if(b[i]==0) //如果说b[i]没有使用的话 
		{
			a[m]=i;
			b[i]=1;
			dfs(m+1);
			b[i]=0;	
		}
	}
	return ;
}
int main()
{
	dfs(0);
	return 0;
}

三重循环大概运行了300s 很烂的做法

找到了一个知识上的错误点 

memset这个函数的作用是将数字以单个字节朱哥拷贝的方式放到指定的内存中

所以memset(a,1,sizeof(a));

是把所有a[i]变成了   16843009

下面上代码

#include<iostream>
#include<cstring>
using namespace std;

int a[10]={0,1,2,3,4,5,6,7,8,9};//用来表示 9个不同的数 
int b[10];//用来判断是否10个数都出现了 
void  fun(int x)
{
	while(x)
	{
			b[x%10]=0;
		   	x=x/10;	    
	}
}
int main()
{
	int i,j,k;
	for(i=1000;i<=9999;i++)
	{
		for(j=1000;j<=9999;j++)
		{
			if(i>j)
			for(k=10;k<=99;k++)
			{	int flag=0;
				for(int s=0;s<=9;s++)
					b[s]=1;
				fun(i);
				fun(j);
				fun(k);
				for(int s=0;s<=9;s++)
				{
					if(b[s]==1)//看看b[]还剩下几个  
					{
					flag++;		
					}
					 
				}
				if((i-j)*k==900&&flag==0)
				cout<<i<<endl;
			}
		}
	}

	return 0;
}



<think>嗯,用户问为什么memset函数的第个参数不能设置为1。首先,我需要回忆一下C语言中memset函数的用法。memset的作用是将某块内存的内容设置为指定的值,函数原型是void *memset(void *ptr, int value, size_t num)。第个参数是int类型,但实际上它会被转换为unsigned char后再填充到内存中每个字节里。 用户可能误以为设置value为1会将每个字节设为1,但实际效果可能不符合预期。比如在初始化int数组时,每个int占4个字节,如果用memset(arr, 1, sizeof(arr)),那么每个字节都是0x01,整个int的值就是0x01010101,十进制是16843009,而不是1。这可能用户预期的将每个元素设为1不同。 需要解释清楚memset是按字节赋值的,而变量类型的存储方式可能让结果看起来不正确。例如,对于char数组,设置为1是正确的,因为每个char占一个字节。但对于int或其他多字节类型,结果会不同。 还要提到常见的正确用法,比如初始化为0,这时不管类型如何,所有字节都是0,结果正确。或者用memset初始化结构体的填充字节为特定模式,但非0的情况需谨慎。 用户可能遇到的问题是想把整型数组元素全设为1,结果发现值不对,于是疑惑为什么不能memset。这时候需要引导他们使用循环逐个赋值,或者使用其他初始化方法。 另外,可能需要注意不同数据类型的字节顺序(大端/小端),但memset的处理字节顺序无关,它只是简单地填充每个字节。 总结回答时要分点说明:函数原理、示例分析、正确用法、替代方案。还要确保引用正确,比如提到C标准库中的定义或相关文档。</think>关于C语言中`memset`函数第个参数不能设置为1的原因,需要从内存操作机制数据类型角度解释。 ### 1. `memset`的底层原理 `memset`的功能是将某块内存的**每个字节**设置为特定值,其函数原型为: $$void \*memset(void \*ptr, int value, size_t num)$$ 第个参数`value`虽然是`int`类型,但实际会被转换为`unsigned char`类型(范围0-255)。例如设置`value=1`时,每个字节将被赋值为`0x01`[^1]。 ### 2. 典型错误示例 若对整型数组执行: ```c int arr[10]; memset(arr, 1, sizeof(arr)); // 每个字节设为0x01 ``` 每个`int`类型变量(假设4字节)的实际值将变为: $$0x01010101 = 16,843,009$$ 而非预期的`1`。 ### 3. 正确使用场景 - ✅ 初始化全零:`memset(arr, 0, sizeof(arr))` - ✅ 字符数组初始化:`char str[10]; memset(str, 'A', 9)` - ❌ 非字符类型的非零初始化需用循环赋值 ### 4. 替代方案 ```c // 将int数组初始化为全1 int arr[10]; for(int i=0; i<10; i++){ arr[i] = 1; // 直接操作数据类型 } ``` [^1]: 根据C99标准第7.21.6.1节,memset的value参数会被隐式转换为unsigned char类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值