附录2:
根据算法(二)写出的程序代码:
/* S、P先生数学谜题*/
/*梁见斌 2005-11-14*/
#include <stdio.h>
#include <stdlib.h>
#define M 2
#define N 99
//初步列出所有可能的p的值(M*M〈= p〈= N*N),并把每一个p的xy组合的个数作为p[i]的值
void possible1_p(int *p);
//根据p的不可能的值的集合 进一步确定 s的不可能的值的集合 ,即设该元素值为s[x+y] = 1;
void possible_us(int *s, int p[]);
//根据s的不可能的值的集合,推出s的可能的值的集合
int possible2_s(int *s);
//根据p的不可能的值的集合,推出p的可能的值的集合
int possible2_p(int *p);
//根据P的话判断出p[]的可能的值的集合
int possible3_p(int *p, int s[], int len_p, int len_s);
//根据S的话判断出s[]的可能的值的集合
int possible3_s(int *s, int p[], int len_s, int len_p);
//根据P和S的可能的值的集合,判断出X,Y的可能的值的集合
int possible_xy(int p[], int s[], int len_s, int len_p, int *px, int *py);
//输出最后的结果
void print(int x[], int y[], int len);
int main( void )
{
int len_s=0, len_p=0, len_xy;
int s[N+N+1]={0}, p[N*N+1]={0}, *ps, *pp;
int x[N]={0}, y[N]={0}, *px, *py;
ps = s;
pp = p;
px = x;
py = y;
possible1_p(pp);//初步列出所有可能的p的值
possible_us(ps, p);//根据p的不可能的值的集合 进一步确定 s的不可能的值的集合
len_s = possible2_s(ps);//根据s的不可能的值的集合,推出s的可能的值的集合
len_p = possible2_p(pp);//根据p的不可能的值的集合,推出p的可能的值的集合
len_p = possible3_p(pp, s, len_p, len_s);//根据P的话判断出p[]的可能的值的集合
len_s = possible3_s(ps, p, len_s, len_p);//根据S的话判断出s[]的可能的值的集合
//根据P和S的可能的值的集合,判断出X,Y的可能的值的集合
len_xy = possible_xy(p, s, len_s, len_p, px, py);
print(x, y, len_xy);//输出最后的结果
system("pause");
return 0;
}
// 寻找p的可能的值的集合,并把构成其值的可能组合的个数作为数组p[]的元素的值
void possible1_p(int *p)
{
int i, x, y;
for(i=M*M; i<=N*N; i++) //穷举p所有的可能值,把构成其值的可能组合的个数存入数组p[]
for(x=M; x<=N; x++) // M<=X<=Y<=N ,X*Y=P
{
y = i/x;
if(y>=M && y<=N && y>=x && x*y==i)
p[i]++;;
if(p[i] > 1) //为节省时间,当p[i] > 1时即可跳出循环,分析下一个数
break;
}
}
//根据p的不可能的值的集合进一步确定 s的不可能的值的集合
void possible_us(int *s, int p[])
{
int i, x, y;
for(i=M*M; i<=N*N; i++) //穷举s所有的可能值,把构成其值的可能组合的个数存入数组s[]
{
if(p[i] == 1) //若构成p[i]的组合是唯一的,则该p不可能,即构成p[i]的两个数被排除
{
for(x=M; x<=N; x++) // M<=X<=Y<=N ,X*Y=P
{
y = i/x;
if(y>=M && y<=N && y>=x && x*y==i)
s[x+y] = 1;//被排除的两个数所构成的s[x+y]元素也被排除
}
}
}
}
//根据s的不可能的值的集合进一步确定 s的可能的值的集合
int possible2_s(int *s)
{
int i, k=0, add[N+N]={0};
for(i=M+M; i<=N+N; i++) //穷举s所有的可能值,数组元素表示构成其值的xy可能组合的个数
{
if(s[i] != 1) //若构成s[i]的组合不是唯一的,则该s是可能的,把它归入add[k]
add[k++] = i;
}
for(i=0; i<k; i++)//把add[k]复制到s[i],得到新的数组s[i]
s[i] = add[i]; //注意此时s[i]中元素的值不再表示构成其值的xy可能组合的个数
return k; //而是表示一个可能的和
}
//根据p不可能的值的集合,推出p的可能的值的集合
int possible2_p(int *p)
{
int i, k=0, mul[N*N]={0};
for(i=M*M; i<=N*N; i++) //穷举p所有的可能值,数组元素表示构成其值的xy可能组合的个数
{
if(p[i] != 1 && p[i] != 0) //若构成p[i]的组合不是唯一的,则该p是可能的,把它归入 mul[k]
mul[k++] = i;
}
for(i=0; i<k; i++) //把mul[k]复制到p[i],得到新的数组p[i]
p[i] = mul[i]; //注意此时p[i]中元素的值不再表示构成其值的xy可能组合的个数
return k; //而是表示一个可能的积
}
//根据P的话判断出p[]的可能的值的集合
int possible3_p(int *p, int s[], int len_p, int len_s)
{
int i, j, x, y;
int k=0, sum=0, mul[N*N]={0};
for(i=0; i<len_p; i++)
{
sum=0;
for(x=M; x<=N; x++) // M<=X<=Y<=N ,X*Y=P
{
y = p[i] / x;
if(y>=M && y<=N && y>=x && x*y==p[i])
for(j=0; j<len_s; j++)
if(x+y == s[j])
sum++; //累积满足x*y==p[i]的xy的组合在s中出现(即同时满足x+y == s[j])的次数
}
if(sum == 1) //若只出现一次,则该xy组合为正确答案之一 ,所以P先生率先知道了答案
mul[k++] = p[i]; //把对应的x*y==p[i]存入数组mul[k]
}
for(i=0; i<k; i++) //把mul[k]复制到p[i],得到新的数组p[i]
p[i] = mul[i]; //注意,S先生很聪明,当P先生说知道答案后,S先生也推出了数组p[i]
return k;
}
//根据S的话判断出s[]的可能的值的集合
int possible3_s(int *s, int p[], int len_s, int len_p)
{
int i, j, x, y;
int k=0, sum=0, add[N+N]={0};
for(i=0; i<len_s; i++)
{
sum=0;
for(x=M; x<=N; x++) // M<=X<=Y<=N ,X*Y=P
{
y = s[i] - x;
if(y>=M && y<=N && y>=x)
for(j=0; j<len_p; j++)
if(x*y == p[j])
sum++; //累积满足x+y==s[i]的xy的组合在p中出现(即同时满足x*y == p[j])的次数
}
if(sum == 1) //若只出现一次,则该xy组合为正确答案之一 ,所以S先生也知道了答案
add[k++] = s[i];//把对应的x+y==s[i]存入数组add[k]
}
for(i=0; i<k; i++) //把add[k]复制到s[i],得到新的数组s[i]
s[i] = add[i];
return k;
}
//根据P和S的可能的值的集合,判断出X,Y的可能的值的集合
int possible_xy(int p[], int s[], int len_s, int len_p, int *px, int *py)
{
int x, y, i, j, k=0;
for(i=0; i<len_s; i++) //遍历s[]
{
for(x=M; x<=s[i]; x++)
{
y = s[i] - x;
if(y>=M && y<=N && y>=x)
for(j=0; j<len_p; j++) //遍历p[]
if(x*y == p[j])
{
px[k] = x; //解不定方程x+y = s
py[k] = y; // x*y = p
k++;
}
}
}
return k;
}
//输出最后的结果
void print(int x[], int y[], int len)
{
int i;
if(len == 0)
printf("No answer !!\n");
else
for(i=0; i<len; i++)
printf("number %d : x=%d, y=%d\n", i+1, x[i], y[i]);
}
评论