USACO 2.1 Ordered Fractions

很简单的一道题

直接找出所有的分数,然后按值排序,去除重复的输出。

my code
/*
ID: superbi1
LANG: C
TASK: frac1
*/
#include
<stdio.h>
#include
<string.h>
#include
<stdlib.h>
#include
<math.h>
#define NL 160*161
#define EP 1e-10

struct Fct{
int a, b;
double val;
}f[NL];
int nf;

int gcd(int a, int b)
{
if (b == 0) return a;
return gcd(b, a%b);
}

int cmp(const void *a, const void *b)
{
struct Fct *x = (struct Fct *)a;
struct Fct *y = (struct Fct *)b;
if (fabs(x->val - y->val) < EP) return 0;
else if (x->val < y->val) return -1;
else return 1;
}

int cmp1(struct Fct *a, struct Fct *b)
{
return a->a - a->b;
}

int main()
{
FILE
*in = fopen("frac1.in", "r");
FILE
*out = fopen("frac1.out", "w");
int n;
int I, K;
int a, b;
fscanf(
in, "%d", &n);
nf
= 0;
f[nf].a
= 0;
f[nf].b
= 1;
f[nf
++].val = 0;
f[nf].a
= 1;
f[nf].b
= 1;
f[nf
++].val = 1;
for (I=1; I<=n; I++) {
for (K=1; K<I; K++) {
int g = gcd(I, K);
f[nf].a
= K/g;
f[nf].b
= I/g;
f[nf
++].val = K*1.0/I;
}
}
qsort(f, nf,
sizeof(f[0]), cmp);
a
= f[0].a;
b
= f[0].b;
for (I=1; I<nf; I++) {
if (a==f[I].a && b==f[I].b) continue;
else {
fprintf(
out, "%d/%d\n", a, b);
a
= f[I].a;
b
= f[I].b;
}
}
fprintf(
out, "%d/%d\n", a, b);
return 0;
}
标程一:

改进:

1.发现这些分数的分子和分母互素

2.排序的时候的小技巧:p1/q1 = p2/q2 --> p1*q2 = p2*q1

stand1
#include <fstream.h>
#include
<stdlib.h>

struct fraction {
int numerator;
int denominator;
};

bool rprime(int a, int b){
int r = a % b;
while(r != 0){
a
= b;
b
= r;
r
= a % b;
}
return(b == 1);
}

int fraccompare (struct fraction *p, struct fraction *q) {
return p->numerator * q->denominator - p->denominator *q->numerator;
}

int main(){
int found = 0;
struct fraction fract[25600];

ifstream filein(
"frac1.in");
int n;
filein
>> n;
filein.close();

for(int bot = 1; bot <= n; ++bot){
for(int top = 0; top <= bot; ++top){
if(rprime(top,bot)){
fract[found].numerator
= top;
fract[found
++].denominator = bot;
}
}
}

qsort(fract, found,
sizeof (struct fraction), fraccompare);

ofstream fileout(
"frac1.out");
for(int i = 0; i < found; ++i)
fileout
<< fract[i].numerator << '/' << fract[i].denominator << endl;
fileout.close();

exit (
0);
}

标程二:

改进:

1.找出这些分数之间的规律,然后直接生成

stand2
#include <stdio.h>
#include
<stdlib.h>
#include
<string.h>
#include
<assert.h>

int n;
FILE
*fout;

/* print the fractions of denominator <= n between n1/d1 and n2/d2 */
void
genfrac(
int n1, int d1, int n2, int d2)
{
if(d1+d2 > n) /* cut off recursion */
return;

genfrac(n1,d1, n1
+n2,d1+d2);
fprintf(fout,
"%d/%d\n", n1+n2, d1+d2);
genfrac(n1
+n2,d1+d2, n2,d2);
}

void
main(
void)
{
FILE
*fin;

fin
= fopen("frac1.in", "r");
fout
= fopen("frac1.out", "w");
assert(fin
!= NULL && fout != NULL);

fscanf(fin,
"%d", &n);

fprintf(fout,
"0/1\n");
genfrac(
0,1, 1,1);
fprintf(fout,
"1/1\n");
}

 

posted @ 2010-05-30 18:50  superbin  阅读(212)  评论(0编辑  收藏  举报