现在的位置: 首页 > 综合 > 正文

Ordered Fractions

2013年05月19日 ⁄ 综合 ⁄ 共 1032字 ⁄ 字号 评论关闭

(1)求最小公倍数和最大公约数

欧几里得公式求最大公约数 gcd(a, b) = gcd(b, a mod b) (a > b)

最小公倍数 = a * b / gcd(a, b)

 

求出1-n的公倍数,然后遍历每个元素,是否符合条件,符合就输出~结果求1-160的公倍数溢出

 

(2)最终还是老实的逐个产生,然后排序,输出

 

(3)一下为USACO给的第二种解答,根据分数的产生规律

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

抱歉!评论已关闭.