USACO :Ordered Fractions解题报告

    水题,枚举加快排,注意舍弃分母和分子可以约分的情况。此外,还有一种类似杨辉三角的数学方法:
    可以把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;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值