您的位置:首页 > 其它

USACO :Ordered Fractions解题报告

2010-04-20 13:40 344 查看
    水题,枚举加快排,注意舍弃分母和分子可以约分的情况。此外,还有一种类似杨辉三角的数学方法:

    可以把0/1和1/1作为“端点”,通过把两个分数的分子相加、分母相加得到的新分数作为中点来递归(如图)

0/1                                                              1/1

                              1/2

                 1/3                      2/3

       1/4              2/5         3/5                 3/4

   1/5      2/7     3/8    3/7   4/7   5/8       5/7         4/5

每一个分数的分子和分母都是由求和得来的,这意味着我们可以通过判断和与N的大小关系来判断递归边界。

 

/*

ID: xpli1

PROG: frac1

LANG: C++

*/

#include <iostream>

#include <fstream>

#include <cstring> 

#include <cstdio>

#include <cmath>

using namespace std;

#define OUT cout

#define IN  cin

ofstream fout ("frac1.out");

ifstream fin ("frac1.in");

typedef struct{

 char s[8];

 double x; 

}fraction;

fraction f[8000];

int N;

int num;

int gcd(int a,int b){

 if(a < b){

  a = a + b;

  b = a - b;

  a = a - b;

 }

 if(b == 0)

  return a;

 else

  return gcd(b,a%b);

}

int cmp(const void* lhs,const void* rhs){

 fraction* f1 = (fraction*)lhs;

 fraction* f2 = (fraction*)rhs;

 return f1->x < f2->x ? -1 : 1;

}

bool Find(char* s){

 for(int i=0; i<num; i++){

  if(strcmp(s,f[i].s) == 0)

   return true;

 }

 return false;

}

void solve(){

 sprintf(f[0].s,"0/1");

 f[0].x = 0;

 sprintf(f[1].s,"1/1");

 f[1].x = 1;

 num = 2;

 int GCD,i,j,ii,jj;

 char ss[8];

 for(i=1; i<=N; i++){  // 分母

  for(j=1; j<i; j++){

   GCD = gcd(i,j);

   ii = i/GCD;

   jj = j/GCD;

   sprintf(ss,"%d/%d",jj,ii);

   if(Find(ss)) continue;

   f[num].x = jj*1.0/ii;

   sprintf(f[num].s,"%d/%d",jj,ii);

   num++;

  }

 }

 qsort(f,num,sizeof(fraction),cmp);

}

int main()

{

 IN >> N;

 solve();

 for(int i=0; i<num; i++)

  OUT << f[i].s << endl;

 return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  struct c