Consider the set of all reduced fractions between 0 and 1 inclusive with denominators less than or equal to N.
Here is the set when N = 5:
0/1 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 1/1
Write a program that, given an integer N between 1 and 160 inclusive, prints the fractions in order of increasing magnitude.
One line with a single integer N.
5
One fraction per line, sorted in order of magnitude.
0/1 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 1/1
简单题:欧几里得求约数+快排
/* ID:nealgav1 PROG:frac1 LANG:C++ */ #include<cstdio> #include<algorithm> using namespace std; class node {public: int x,y; float num; }root[123456]; int Euclid(int a,int b) { if(b==0)return a; Euclid(b,a%b); } bool cmp(node a,node b) { return a.num<b.num; } int main() {freopen("frac1.in","r",stdin); freopen("frac1.out","w",stdout); int m,n,km,nil; scanf("%d",&m); km=m; printf("0/1\n"); nil=0; for(int j=1;j<m;j++,km--) for(int i=1;i<km;i++) { n=Euclid(i,km); root[++nil].x=i/n;root[nil].y=km/n;root[nil].num=float(i)/float(km); } sort(root+1,root+nil+1,cmp); km=m;nil=1; for(int j=1;j<m;j++,km--) for(int i=1;i<km;i++,nil++) if(root[nil].x==root[nil-1].x&&root[nil].y==root[nil-1].y) continue; else printf("%d/%d\n",root[nil].x,root[nil].y); printf("1/1\n"); }
USER: Neal Gavin Gavin [nealgav1] TASK: frac1 LANG: C++ Compiling... Compile: OK Executing... Test 1: TEST OK [0.011 secs, 4792 KB] Test 2: TEST OK [0.011 secs, 4792 KB] Test 3: TEST OK [0.000 secs, 4792 KB] Test 4: TEST OK [0.000 secs, 4792 KB] Test 5: TEST OK [0.000 secs, 4792 KB] Test 6: TEST OK [0.000 secs, 4792 KB] Test 7: TEST OK [0.000 secs, 4792 KB] Test 8: TEST OK [0.011 secs, 4792 KB] Test 9: TEST OK [0.011 secs, 4792 KB] Test 10: TEST OK [0.011 secs, 4792 KB] Test 11: TEST OK [0.011 secs, 4792 KB] All tests OK.YOUR PROGRAM ('frac1') WORKED FIRST TIME! That's fantastic -- and a rare thing. Please accept these special automated congratulations.
Here are the test data inputs:
------- test 1 ---- 1 ------- test 2 ---- 2 ------- test 3 ---- 4 ------- test 4 ---- 7 ------- test 5 ---- 10 ------- test 6 ---- 15 ------- test 7 ---- 24 ------- test 8 ---- 50 ------- test 9 ---- 75 ------- test 10 ---- 100 ------- test 11 ---- 160Keep up the good work!
Thanks for your submission!
Ordered FractionsRuss Cox
Here's a very fast, straightforward solution from Alex Schwedner:
#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); }
Here's a super fast solution from Russ:
We notice that we can start with 0/1 and 1/1 as our ``endpoints'' and recursively generate the middle points by adding numerators and denominators.
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
Each fraction is created from the one up to its right and the one up to its left. This idea lends itself easily to a recursion that we cut off when we go too deep.
#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"); }