整数1~9填入□□□□×□=□□□□,各数不重复,纠正以下代码

aszhinian 2012-05-18 07:52:17
只改以下代码,保证思路不变,自己写的绕道,我有答案。

思路:先将两个4位数限定范围,分别用以上3个数拆成9个数,判断9个数均不为零且互不相等


#include<stdio.h>
#define MAX 9876 //1~9组成的最大数四位数
#define MIN 1234 //1~9组成的最小数四位数
int main() {
int i,j,k,a[9],*p=a,m,n;
for(i=1;i<=9;i++) {
for(j=MIN;j<=MAX/i;j++) {
k=i*j;
*p=j/1000;*(p+1)=j/100%10;*(p+2)=j/10%10;*(p+3)=j%10;
*(p+4)=i;
*(p+5)=k/1000;*(p+6)=k/100%10;*(p+7)=k/10%10;*(p+8)=k%10;
/*以下为前面数与其后所有数比较*/
for(m=0;m<8&&a[m]!=0;m++) {
for(n=m+1;n<9&&a[n]!=0;n++) {
if(a[m]==a[n]) continue;
}
}
printf("%d×%d=%d\n",j,i,k);
}
}
}
...全文
445 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
muyi66 2012-05-18
  • 打赏
  • 举报
回复
按照你的思路来写这个程序,实际上不需要先拆数字再找重复,完全可以在拆解的同时进行判定:

#include<stdio.h>
#define MAX 9876
#define MIN 1234
int main() {
int i,j,k,a[10]={1},m,n,found;
for(i=1;i<9;i++) {
for(j=MIN;j<=MAX/i;j++) {
for (n=1;n<10;++n)
a[n]=0;
found=0;
a[i]=1; /* 数字i已有 */
m=j;
while ((!(found+=a[m%10]++))&&(m=m/10)); /* 检查j里是否有重复或0 */
m=k=j*i;
while ((!(found+=a[m%10]++))&&(m=m/10)); /* 检查k里是否有重复或0 */
if (found==0)
printf("%d×%d=%d\n",j,i,k);
}
}
}
nice_cxf 2012-05-18
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

8#的代码调试过吗?光这一句就有问题
int multiOK =3*5*7*11*13*17*19*23*29;
这个数是3234846615,超过了整数的最大范围2^31-1.
[/Quote]
的确没调试,如果这样会越界,那么似乎改成unsigned就可以勉强不越界,还不行的话可以把数组29去掉前边加上1,multiOK *29换成*2,这样就不会有问题了 因为是确定9个数乘积,这样就算有1也没关系
liangbch 2012-05-18
  • 打赏
  • 举报
回复
明白了,楼上的代码中,1-9每个数字对应一个素数1对应于3,2对应于5等,,素数2弃之不用。如果各个数字个出现一次,其对应的素数的乘积就是从素数第3个素数到第10个素数的乘积。
muyi66 2012-05-18
  • 打赏
  • 举报
回复

#include<stdio.h>
#define MAX 9876 //1~9组成的最大数四位数
#define MIN 1234 //1~9组成的最小数四位数
int main() {
int i,j,k,a[9],*p=a,m,n,found;
for(i=1;i<9;i++) { /* i明显不可能为9 */
for(j=MIN;j<=MAX/i;j++) {
if ((k=i*j)>9999) /* 乘积有可能超过4位数 */
break;
*p=j/1000;*(p+1)=j/100%10;*(p+2)=j/10%10;*(p+3)=j%10;
*(p+4)=i;
*(p+5)=k/1000;*(p+6)=k/100%10;*(p+7)=k/10%10;*(p+8)=k%10;

found=1; /* 默认找到 */
for(m=0;m<8 && found;m++) { /* 循环条件里不能判断数组元素是否为0,否则会导致无法正确判定 */
for(n=m+1;n<9;n++) {
if(a[m]==a[n]||a[m]==0||a[n]==0)
{
found=0; /* 违背则复位 */
break;
}
}
}
if (found) /* 找到才显示 */
printf("%d×%d=%d\n",j,i,k);
}
}
}
liangbch 2012-05-18
  • 打赏
  • 举报
回复
郑重申明一下,8#的代码除了那一处warning外,结果是对的。正在理解算法中。。。
liangbch 2012-05-18
  • 打赏
  • 举报
回复
8#的代码调试过吗?光这一句就有问题
int multiOK =3*5*7*11*13*17*19*23*29;
这个数是3234846615,超过了整数的最大范围2^31-1.

nice_cxf 2012-05-18
  • 打赏
  • 举报
回复
上边有点疏忽了应该是b[10]
nice_cxf 2012-05-18
  • 打赏
  • 举报
回复
实际上真的想优化的话倒是可以用那个素数相乘的办法
int b[9]={2,3,5,7,11,13,17,19,23,29};
int multiOK =3*5*7*11*13*17*19*23*29;
int multi=1;
for (x=0;x<9;x++)
multi *=b[a[x]];
if (multi == multiOK )
{
printf("%d×%d=%d\n",j,i,k);
}

liangbch 2012-05-18
  • 打赏
  • 举报
回复
奇怪,4#代码丢了,重发一遍
#include <stdio.h>
#include <memory.h>

#define MAX 9876 //1~9组成的最大数四位数
#define MIN 1234 //1~9组成的最小数四位数

int main()
{
int i,j,k,a[9],*p=a;

for(i=1;i<=9;i++) {
for(j=MIN;j<=MAX/i;j++) {
k=i*j;
*p=j/1000;*(p+1)=j/100%10;*(p+2)=j/10%10;*(p+3)=j%10;
*(p+4)=i;
*(p+5)=k/1000;*(p+6)=k/100%10;*(p+7)=k/10%10;*(p+8)=k%10;
/*以下为前面数与其后所有数比较*/

/*
for(m=0;m<8&&a[m]!=0;m++) {
for(n=m+1;n<9&&a[n]!=0;n++) {
if(a[m]==a[n]) continue;
}
}
*/
/*
上面的代码是一个2重循环,复杂度较高,实现也不优雅。其实仅仅需要在数组a中,检查每个数字
是否出现了1次以上或者没有出现过即可.
这个问题有更好的实现。数组digMap[1]表示数字“1”出现的次数,digMap[2]表示数字“2”出现的次数,
以此类推。先将所有数字的出现次数都初始化为0,然后检查数组a个各个数字,如果是x,则digMap[x]++。
检查完成,再查看digMap中是否有某个数字出现的次数不为1,如果所有数字出现的次数等于1,输出这个组合
*/
{
int x;
int ok;
int digMap[10];
memset(digMap,0,sizeof(digMap)); //

for (x=0;x<9;x++)
digMap[a[x]]++;
ok=1;
for (x=1;x<=9;x++)
{
if ( digMap[x]!=1) //某个数字从为出现或者出现次数>1,那么,它不是我们想要的
{
ok=0; break;
}
}
if (ok)
printf("%d×%d=%d\n",j,i,k);
}
}
}
}

/*
这个程序的运行结果是:
1738×4=6952
1963×4=7852
*/


liangbch 2012-05-18
  • 打赏
  • 举报
回复
4楼代码的运行结果是:
1738×4=6952
1963×4=7852
laoyang103 2012-05-18
  • 打赏
  • 举报
回复
9个数的全排列
liangbch 2012-05-18
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <memory.h>

#define MAX 9876 //1~9组成的最大数四位数
#define MIN 1234 //1~9组成的最小数四位数

int main()
{
int i,j,k,a[9],*p=a;

for(i=1;i<=9;i++) {
for(j=MIN;j<=MAX/i;j++) {
k=i*j;
*p=j/1000;*(p+1)=j/100%10;*(p+2)=j/10%10;*(p+3)=j%10;
*(p+4)=i;
*(p+5)=k/1000;*(p+6)=k/100%10;*(p+7)=k/10%10;*(p+8)=k%10;
/*以下为前面数与其后所有数比较*/

/*
for(m=0;m<8&&a[m]!=0;m++) {
for(n=m+1;n<9&&a[n]!=0;n++) {
if(a[m]==a[n]) continue;
}
}
*/
/*
上面的代码是一个2重循环,复杂度较高,实现也不优雅。其实仅仅需要在数组a中,检查每个数字
是否出现了1次以上或者没有出现过即可.
这个问题有更好的实现。数组digMap[1]表示数字“1”出现的次数,digMap[2]表示数字“2”出现的次数,
以此类推。先将所有数字的出现次数都初始化为0,然后检查数组a个各个数字,如果是x,则digMap[x]++。
检查完成,再查看digMap中是否有某个数字出现的次数不为,如果所有数字出现的次数等于1,输出这个组合
*/
{
int x;
int ok;
int digMap[10];
memset(digMap,0,sizeof(digMap)); //

for (x=0;x<9;x++)
digMap[a[x]]++;
ok=1;
for (x=1;x<=9;x++)
{
if ( digMap[x]!=1) //某个数字从为出现或者出现次数>1,那么,它不是我们想要的
{
ok=0; break;
}
}
if (ok)
printf("%d×%d=%d\n",j,i,k);
}
}
}
}
laoyang103 2012-05-18
  • 打赏
  • 举报
回复
很明显是个全排列嘛 9个数填入9个空 深度优先搜索去搞
nice_cxf 2012-05-18
  • 打赏
  • 举报
回复
最后看是否重复可以排序然后memcmp把?i取值从1-9可以修改为2-8,其他1楼应该改对了
W170532934 2012-05-18
  • 打赏
  • 举报
回复
#define MAX 9876  //1~9组成的最大数四位数
#define MIN 1234 //1~9组成的最小数四位数
int main() {
bool bFind;
int i,j,k,a[9],*p=a,m,n;
for(i=1;i<=9;i++) {
for(j=MIN;j<=MAX/i;j++) {
k=i*j;
*p=j/1000;*(p+1)=j/100%10;*(p+2)=j/10%10;*(p+3)=j%10;
*(p+4)=i;
*(p+5)=k/1000;*(p+6)=k/100%10;*(p+7)=k/10%10;*(p+8)=k%10;
/*以下为前面数与其后所有数比较*/
bFind = true;
for(m=0;m<8;m++) {
for(n=m+1;n<9;n++) {
if(a[m]==a[n]||a[m]==0||a[n]==0) {
bFind = false;
break;
// continue;
}
}
if(!bFind)
break;
}
if(bFind)
printf("%d×%d=%d\n",j,i,k);
}
}
}
aszhinian 2012-05-18
  • 打赏
  • 举报
回复

/*5个人分数依次结在1、14、5、13、15楼*/
1.#1 //运行有点问题,C语言无bool型,像13楼那样1或0就行了
2.#2、8、9、14 //不清楚memcmp函数
3.#3、5 //不会全排列呀
4.#4、6、7、10、11、13 //通过你改的,知道如何判断各数不相同了
5.#12、15 //思考15楼代码ing……

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧