正文

"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]);

}

 

阅读(2606) | 评论(0)


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

评论

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