正文

"S、P先生数学谜题"算法分析及源代码(3)2005-11-13 13:55:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/goal00001111/6863.html

分享到:

附录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]); }  

阅读(2738) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册