| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 779 人关注过本帖
标题:[求助]小红转换题,循环处有问题找不出来
取消只看楼主 加入收藏
iwfy
Rank: 1
等 级:新手上路
威 望:2
帖 子:888
专家分:0
注 册:2007-2-23
收藏
 问题点数:0 回复次数:7 
[求助]小红转换题,循环处有问题找不出来

小明与小红的故事:http://acm.hit.edu.cn/ojs/show.php?Proid=100082&Contestid=11
我的思路是这样的:一个小10位的n位数,可以这样分割,分割0次即保留全部;分割1次为两段有n-1种组合;分割2次有n-2种组合;分割3次有n-3种组合、、、每分成一种组合就对行成的组合分别平方然后相加成新的数判断是否等于给定的数,不等的话再重新开始分割直到第8次、、、、具体代码:
#include <stdio.h>
#include <math.h>
int zwz,ci,zh,min; //zh=转换次数不能大与8,zwz为用户输入数的位置,min最少次数
long s[10][2],sz[9][10]; //sz[][]存放被分解开的各个数,s[10][2]存放用户输入的几组数
int qws(long a) //取a的位数
{
int c;
long a2=a;
for(c=0;a2!=0;a2/=10)c++;
return c;
} //判断给定数是几位数然后返回n
int fenjie(long a,int b) //a=要分的数,b=分成的段数,c=a的长度
{
int n,i,j=b,xh,cf=ci,kk; //j=数组当前位置cf表示进入此函数时要分解的段数
long a2; //kk,n,i,xh都是为了循环计数
if(zh>8)return 0;
n=qws(a)-b+1; //b=当前进入的循环次数,也是数组sz[zh][?]当前位置
if(b==0) //当把a从长度分割到1个时即分0次时
{
if(a<3163) //当a值大于3162时,它的平方就大于10000000
{
a2=a*a; //a的平方带入到下个循环
if(a2==s[zwz][1])
{
if(min>zh)min=zh+1;
else return 0;
}
else
if(zh>=min) return 0; //如果循环次数大于或等于已知最小步数min则返回
else
{
++zh; //并给zh增加1
zhhuan(a2);
--zh; //退出函数后zh再减1
}
}
else return 0;
}
else
{
for(i=0;n-i>0;i++) //把给定新数value分解成n块存放到数组sz[]中
{ //当某个值大于3162时,它的平方就大于10000000
a2=a%(long)pow10(i);
if(a2!=0 && a2<3163)
sz[zh][j]=a%(long)pow10(i);
else continue; //跳过0和平方大于10000000的
if(b==1) //当循环到达最里层
{
if(a!=0)
sz[zh][0]=a/(long)pow10(i);
else sz[zh][0]=a;
// printf(" cf=%d,zh=%d\n",cf,zh);
a2=0; //用来计算各个平方和
for(xh=0;xh<cf+1;xh++) //每次分解完成后计算各个平方然后相加
{ //同时判断是不是超出8次,是否超过10000000
// printf("%ld ",sz[zh][xh]);
a2=a2+sz[zh][xh]*sz[zh][xh];
if(a2>10000000) break;
}
// getch();
if(a2>10000000) continue ; //如果超出,到下一个循环
else if(a2==s[zwz][1])//相加结果正是且没超过8次
{
if(zh<min)
{
for(kk=0;kk<=zh;kk++) ////////////////可以看到转换过程
{
printf("\nzh=%d: ",kk);
for(xh=0;sz[kk][xh]!=0;xh++)printf("%ld ",sz[kk][xh]);
} ////////////////用来观察转换过程
printf("a2=%ld,min=%d,zh=%d\n",a2,min,zh);////////////
min=zh; //准备返回到调用此函数处
}
return 0;
}
else if(a2<10000000 && zh<min)
{
++zh; //准备分解新合成的数
zhhuan(a2);
--zh;
}

}
else
{
fenjie(a/(long)pow10(i),b-1);
}
}
}
return 0;
}
zhhuan(long a)
{
int ch,n;
if(zh>8)return;
ch=qws(a); //ch=取a的长度
while(ch>0)
{
if(ch==1 && a<3163)sz[zh][0]=a;
sz[zh][ch]=0; //没分之前给后一个位置0方便以后逐个输出
ci=--ch; //分解次数,a的位数
fenjie(a,ch); //ch表示把a分几次
}
return ;
}
main()
{
int i;
for(i=0;i<2;i++) //先测试两组,全部通过再改
scanf("%ld%ld",&s[i][0],&s[i][1]);
while(zwz<i)
{
zh=0; //转换次数清0
min=10; //min=10重新找步数少的方法
zhhuan(s[zwz][0]); //zwz=正在处理的那一组的位置
zwz+=1;
printf("%d , %d\nNext:%ld %ld\npress any key to continue!",zwz,min>8?min=-1:min,s[zwz][0],s[zwz][1]);
getch();
}
getch();
}
不知道怎么回事,能依次分解第二组第一个数但是判断的还是第一组的第二个数,而且while循环也退不出来,代码本来就很乱,变量也多,找错误的时间比写出代码的时间都长,找的头疼的很,希望交流指点下

搜索更多相关主题的帖子: include 故事 用户 
2007-03-26 02:53
iwfy
Rank: 1
等 级:新手上路
威 望:2
帖 子:888
专家分:0
注 册:2007-2-23
收藏
得分:0 
是很乱,现在头疼,还没找到什么原因用来控制循环的变量竟然到最后不自增1退不出循环,虽然想有别的办法能解决,但还是想知道这个代码为什么退不出

英语不好还想学编程??逆天之路,不由分说!! 数学太差还想学编程??离经叛道,义无返顾!!
2007-03-27 18:14
iwfy
Rank: 1
等 级:新手上路
威 望:2
帖 子:888
专家分:0
注 册:2007-2-23
收藏
得分:0 
是啊,是分三次得到四段,想想分的是一根有n个小节的甘蔗,分三次是不是四段,是不是n-3次分法

英语不好还想学编程??逆天之路,不由分说!! 数学太差还想学编程??离经叛道,义无返顾!!
2007-03-27 19:09
iwfy
Rank: 1
等 级:新手上路
威 望:2
帖 子:888
专家分:0
注 册:2007-2-23
收藏
得分:0 
数字:1126425
甘蔗:()--1--()--1--()--6--()--6--()--4--()--2--()--5--()
西安的甘蔗一块3一斤,想吃没钱买

英语不好还想学编程??逆天之路,不由分说!! 数学太差还想学编程??离经叛道,义无返顾!!
2007-03-27 19:15
iwfy
Rank: 1
等 级:新手上路
威 望:2
帖 子:888
专家分:0
注 册:2007-2-23
收藏
得分:0 
那就是表达错了,但在代码里没错

英语不好还想学编程??逆天之路,不由分说!! 数学太差还想学编程??离经叛道,义无返顾!!
2007-03-27 19:18
iwfy
Rank: 1
等 级:新手上路
威 望:2
帖 子:888
专家分:0
注 册:2007-2-23
收藏
得分:0 
分割代码,一开始是从这里开始想的
#include<stdio.h>
#include<math.h>
int ci,sw; /* 123456789 */
long shuzu[10];
int qws(long a) /* 取a的位数 */
{
int n;
for(n=0;a%10!=0;a/=10) n++;
return n;
}
int fenjie(long a,int b) /* a=要分的数,b=分成的段数 */
{
int n,i,j=b,xh; /* j=数组当前位置 */
n=qws(a)-b+1; /* b=当前进入的循环次数,也是数组当前位置 */
for(i=0;n-i>0;i++)
{
if(a%(long)pow10(i)!=0)shuzu[j]=a%(long)pow10(i);
else continue;
if(b==1) /* 当循环到达最里层 */
{
if(a!=0)
{
shuzu[0]=a/(long)pow10(i);
}
else shuzu[0]=a;
printf("\n");
for(xh=0;xh<ci+1;xh++) printf("%d=%ld ",xh,shuzu[xh]);
}
else
fenjie(a/(long)pow10(i),b-1);
}
}
main()
{
long i,j,ja;
int n,k;
scanf("%ld %d",&i,&ci);
j=i;
sw=ci;
ja=fenjie(i,--ci);
getch();
}

英语不好还想学编程??逆天之路,不由分说!! 数学太差还想学编程??离经叛道,义无返顾!!
2007-03-27 19:24
iwfy
Rank: 1
等 级:新手上路
威 望:2
帖 子:888
专家分:0
注 册:2007-2-23
收藏
得分:0 
是这样的,每分一次就计算平方和判断条件,不满足再把和带到函数在分一直到进入第8次函数,还不满足就退到第7次,第7次进行第二次分割,再计算,再进入第8次不满足在退到7次,7次分3次。。。。直到7次的所以可能组合完就退到6次,分6的第二,一直这样往前退,中途记住满足条件的最小次数

英语不好还想学编程??逆天之路,不由分说!! 数学太差还想学编程??离经叛道,义无返顾!!
2007-03-27 19:39
iwfy
Rank: 1
等 级:新手上路
威 望:2
帖 子:888
专家分:0
注 册:2007-2-23
收藏
得分:0 
#include <stdio.h>
#include <math.h>
int zwz,ci,zh,min; /*zh=转换次数不能大与8,zwz为用户输入数的位置,min最少次数*/
long s[10][2],sz[9][10],ab; /* sz[][]存放被分解开的各个数,s[10][2]存放用户输入的几组数 */
int qws(long a) /* 取a的位数 */
{
int c;
long a2=a;
for(c=0;a2!=0;a2/=10)c++;
return c;
} /* 判断给定数是几位数然后返回n */
int fenjie(long a,int b) /* a=要分的数,b=分成的段数,c=a的长度 */
{
int n,i,j=b,xh,cf=ci,kk; /* j=数组当前位置cf表示进入此函数时要分解的段数 */
long a2; /* kk,n,i,xh都是为了循环计数 */
if(zh>8)return 0;
n=qws(a)-b+1; /* b=当前进入的循环次数,也是数组sz[zh][?]当前位置 */
if(b==0) /* 当把a从长度分割到1个时即分0次时 */
{
if(a<3163) /* 当a值大于3162时,它的平方就大于10000000 */
{
a2=a*a; /* a的平方带入到下个循环 */
if(a2==ab)
{
if(min>zh)min=zh+1;
else return 0;
}
else
if(zh>=min) return 0; /* 如果循环次数大于或等于已知最小步数min则返回 */
else
{
++zh; /* 并给zh增加1 */
zhhuan(a2);
--zh; /* 退出函数后zh再减1 */
}
}
else return 0;
}
else
{
for(i=0;n-i>0;i++) /* 把给定新数value分解成n块存放到数组sz[]中 */
{ /* 当某个值大于3162时,它的平方就大于10000000 */
a2=a%(long)pow10(i);
if(a2!=0 && a2<3163)
sz[zh][j]=a%(long)pow10(i);
else continue; /* 跳过0和平方大于10000000的 */
if(b==1) /* 当循环到达最里层 */
{
if(a!=0)
sz[zh][0]=a/(long)pow10(i);
else sz[zh][0]=a;
a2=0; /* 用来计算各个平方和 */
for(xh=0;xh<cf+1;xh++) /* 每次分解完成后计算各个平方然后相加 */
{ /* 同时判断是不是超出8次,是否超过10000000 */
a2=a2+sz[zh][xh]*sz[zh][xh];
if(a2>10000000) break;
}
if(a2>10000000) continue ; /* 如果超出,到下一个循环 */
else if(a2==ab) /* 相加结果正是且没超过8次 */
{
if(zh<min)
{
/* 屏蔽以下代码可以跳过输出转换过程*/
for(kk=0;kk<=zh;kk++) /* //////////////可以看到转换过程 */
{
printf("\nzh=%d: ",kk);
for(xh=0;sz[kk][xh]!=0;xh++)printf("%ld ",sz[kk][xh]);
} /* //////////////用来观察转换过程 */
printf("a2=%ld,min=%d,zh=%d\n",a2,min,zh);/* ////////// */
/* 屏蔽以上代码可以跳过输出转换过程*/
min=zh; /* 准备返回到调用此函数处 */
}
}
else if(a2<10000000 && zh<min)
{
++zh; /* 准备分解新合成的数 */
zhhuan(a2);
--zh;
}
}
else
{
fenjie(a/(long)pow10(i),b-1);
}
}
}
return 0;
}
zhhuan(long a)
{
int ch,n;
if(zh>8)return;
ch=qws(a); /* ch=取a的长度 */
while(ch>0)
{
if(ch==1 && a<3163)sz[zh][0]=a;
sz[zh][ch]=0; /* 没分之前给后一个位置0方便以后逐个输出 */
ci=--ch; /* 分解次数,a的位数 */
fenjie(a,ch); /* ch表示把a分几次 */
}
return ;
}
main()
{
int i,j=0;
for(i=0;i<2;i++) /* 先测试两组,全部通过再改 */
scanf("%ld%ld",&s[i][0],&s[i][1]);
while(j<i)
{
zh=0; /* 转换次数清0 */
min=10; /* min=10重新找步数少的方法 */
ab=s[j][1];
zhhuan(s[j][0]); /* zwz=正在处理的那一组的位置 */
++j;
printf("%d , %d\nNext:%ld %ld\npress any key to continue!\n",j,min>8?min=-1:min,s[j][0],s[j][1]);
getch();
if(j>=i)break;
zwz=j;
}
getch();
}
把原来需要得到的数变量换成了ab,增加了变量j替换zwz控制循环和s[][]下标

英语不好还想学编程??逆天之路,不由分说!! 数学太差还想学编程??离经叛道,义无返顾!!
2007-03-27 20:25
快速回复:[求助]小红转换题,循环处有问题找不出来
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018743 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved