题目

题目描述

给定一个数N(1<=N<=160),需要产生所有的分数,这些分数的值必须要在0~1之间。而且每个分数的分母不能超过N。如下例所示:

N = 5
产生所有的分数:0/1 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 1/1

样例输入

5

样例输出

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

解题思路

这个题目最一开始我走了一些弯路,想得太复杂,结果第一发就超时了。后来静下心来算了想了下,发现枚举加排序速度就已经很快了。所以就实现了一下,通过。

解题代码

/*
ID: yinzong2
PROG: frac1
LANG: C++11
*/
#define MARK
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 170;
int N;
struct Frac {
int num;
int deno;
};
vector<Frac> lst; bool cmp(Frac A, Frac B) {
int temp1 = A.num*B.deno;
int temp2 = A.deno*B.num;
return temp1 < temp2;
} int GCD(int x, int y) {
if (0 == y) return x;
return GCD(y, x%y);
} Frac afterGCD(Frac f) {
int gcd = GCD(f.num, f.deno);
f.num /= gcd;
f.deno /= gcd;
return f;
} int main() {
#ifdef MARK
freopen("frac1.in", "r", stdin);
freopen("frac1.out", "w", stdout);
#endif // MARK
while (cin >> N) {
cout << "0/1" << endl;
if (N != 1) {
lst.clear();
for (int i = N; i >= 2; --i) {
for (int j = 1; j < i; ++j) {
Frac f;
f.num = j;
f.deno = i;
lst.push_back(f);
}
}
sort(lst.begin(), lst.end(), cmp);
int len = lst.size();
Frac pre;
pre = afterGCD(lst[0]);
cout << pre.num << "/" << pre.deno << endl;
// 对于排序后的数据进行去重
for (int i = 1; i < len; ++i) {
lst[i] = afterGCD(lst[i]);
if (lst[i].num == pre.num && lst[i].deno == pre.deno) continue;
cout << lst[i].num << "/" << lst[i].deno << endl;
pre = lst[i];
}
}
cout << "1/1" << endl;
}
}
/*
Executing...
Test 1: TEST OK [0.000 secs, 4180 KB]
Test 2: TEST OK [0.000 secs, 4180 KB]
Test 3: TEST OK [0.000 secs, 4180 KB]
Test 4: TEST OK [0.014 secs, 4180 KB]
Test 5: TEST OK [0.014 secs, 4180 KB]
Test 6: TEST OK [0.014 secs, 4180 KB]
Test 7: TEST OK [0.028 secs, 4180 KB]
Test 8: TEST OK [0.070 secs, 4180 KB]
Test 9: TEST OK [0.056 secs, 4180 KB]
Test 10: TEST OK [0.056 secs, 4188 KB]
Test 11: TEST OK [0.140 secs, 4188 KB] All tests OK.
*/

解题思路(type2)

之后看了看官方的题解,发现第一个解法就是用的枚举加排序,但是有个优化的地方我之前没有考虑。我们最终枚举出来的所有的分数,分子分母应该都是互质的。所以我们对于所有分子分母互质的分数进行排序输出即可。

解题代码

/*
ID: yinzong2
PROG: frac1
LANG: C++11
*/
#define MARK
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 170;
int N;
struct Frac {
int num;
int deno;
};
vector<Frac> lst; bool cmp(Frac A, Frac B) {
int temp1 = A.num*B.deno;
int temp2 = A.deno*B.num;
return temp1 < temp2;
} int GCD(int x, int y) {
if (0 == y) return x;
return GCD(y, x%y);
} int main() {
#ifdef MARK
freopen("frac1.in", "r", stdin);
freopen("frac1.out", "w", stdout);
#endif // MARK
while (cin >> N) {
cout << "0/1" << endl;
if (N != 1) {
lst.clear();
for (int i = N; i >= 2; --i) {
for (int j = 1; j < i; ++j) {
Frac f;
f.num = j;
f.deno = i;
if (GCD(f.num, f.deno) != 1) continue;
lst.push_back(f);
}
}
sort(lst.begin(), lst.end(), cmp);
int len = lst.size();
for (int i = 0; i < len; ++i) {
cout << lst[i].num << "/" << lst[i].deno << endl;
}
}
cout << "1/1" << endl;
}
}
/*
Executing...
Test 1: TEST OK [0.000 secs, 4180 KB]
Test 2: TEST OK [0.000 secs, 4180 KB]
Test 3: TEST OK [0.000 secs, 4180 KB]
Test 4: TEST OK [0.000 secs, 4180 KB]
Test 5: TEST OK [0.000 secs, 4180 KB]
Test 6: TEST OK [0.000 secs, 4180 KB]
Test 7: TEST OK [0.000 secs, 4180 KB]
Test 8: TEST OK [0.014 secs, 4180 KB]
Test 9: TEST OK [0.028 secs, 4180 KB]
Test 10: TEST OK [0.056 secs, 4180 KB]
Test 11: TEST OK [0.140 secs, 4188 KB] All tests OK.
*/

解题思路(type3)

官方第二个解法很巧妙。是找到一个数学规律,直接可以打印所有的数字,时间复杂度为O(N)。具体可以看这里

解题代码

/*
ID: yinzong2
PROG: frac1
LANG: C++11
*/
#define MARK
#include <iostream>
#include <cstdio>
using namespace std; int N; void generateFrac(int num1, int denom1, int num2, int denom2) {
if (denom1 + denom2 > N) return ;
generateFrac(num1, denom1, num1+num2, denom1+denom2);
cout << num1+num2 << "/" << denom1+denom2 << endl;
generateFrac(num1+num2, denom1+denom2, num2, denom2);
} int main() {
#ifdef MARK
freopen("frac1.in", "r", stdin);
freopen("frac1.out", "w", stdout);
#endif // MARK
while (cin >> N) {
cout << "0/1" << endl;
generateFrac(0, 1, 1, 1);
cout << "1/1" << endl;
}
return 0;
}
/*
Executing...
Test 1: TEST OK [0.000 secs, 4176 KB]
Test 2: TEST OK [0.000 secs, 4176 KB]
Test 3: TEST OK [0.000 secs, 4176 KB]
Test 4: TEST OK [0.000 secs, 4176 KB]
Test 5: TEST OK [0.000 secs, 4176 KB]
Test 6: TEST OK [0.000 secs, 4176 KB]
Test 7: TEST OK [0.000 secs, 4176 KB]
Test 8: TEST OK [0.014 secs, 4176 KB]
Test 9: TEST OK [0.028 secs, 4176 KB]
Test 10: TEST OK [0.056 secs, 4176 KB]
Test 11: TEST OK [0.140 secs, 4176 KB] All tests OK.
*/

USACO Section 2.1 Ordered Fractions 解题报告的更多相关文章

  1. USACO Section2.1 Ordered Fractions 解题报告

    frac1解题报告 —— icedream61 博客园(转载请注明出处)---------------------------------------------------------------- ...

  2. USACO Section 1.3 Prime Cryptarithm 解题报告

    题目 题目描述 牛式的定义,我们首先需要看下面这个算式结构: * * * x * * ------- * * * <-- partial product 1 * * * <-- parti ...

  3. USACO Section 1.4 Arithmetic Progressions 解题报告

    题目 题目描述 现在给你一个数集,里面的数字都是由p^2+q^2这种形式构成的0 <= p,q <= M,我现在需要你在其中找出一个长为N的等差数列,数列中的第一个数字为a,公差为b,当你 ...

  4. USACO Section 1.3 Combination Lock 解题报告

    题目 题目描述 农夫John的牛从农场逃脱出去了,所以他决定用一个密码锁来把农场的门锁起来,这个密码锁有三个表盘,每个表盘都是环形的,而且上面刻有1~N,现在John设了一个开锁密码,而且这个锁的设计 ...

  5. USACO Section 1.3 Barn Repair 解题报告

    题目 题目描述 某农夫有一个养牛场,所有的牛圈都相邻的排成一排(共有S个牛圈),每个牛圈里面最多只圈养一头牛.有一天狂风卷积着乌云,电闪雷鸣,把牛圈的门给刮走了.幸运的是,有些牛因为放假,所以没在自己 ...

  6. USACO Section 1.3 Mixing Milk 解题报告

    题目 题目描述 Merry Milk Makers 公司的业务是销售牛奶.它从农夫那里收购N单位的牛奶,然后销售出去.现在有M个农夫,每个农夫都存有一定量的牛奶,而且每个农夫都会有自己的定价.假设所有 ...

  7. USACO Section 1.2 Dual Palindromes 解题报告

    题目 题目描述 有一些数(如 21),在十进制时不是回文数,但在其它进制(如二进制时为 10101)时就是回文数. 编一个程序,从文件读入两个十进制数N.S.然后找出前 N 个满足大于 S 且在两种以 ...

  8. USACO Section 1.2 Palindromic Squares 解题报告

    题目 题目描述 输入一个基数B,现在要从1到300之间找出一些符合要求的数字N.如果N的平方转换成B进制数之后是一个回文串,那么N就符合要求.我们将N转换成B进制数输出,然后再将N的平方转换成B进制数 ...

  9. USACO Section 1.2 Milking Cows 解题报告

    题目 题目描述 有3个农夫每天早上五点钟便起床去挤牛奶,现在第一个农夫挤牛奶的时刻为300(五点钟之后的第300个分钟开始),1000的时候结束.第二个农夫从700开始,1200结束.最后一个农夫从1 ...

随机推荐

  1. 二、Unity Editor模式下,操作选中对象

    使用Unity提供的工具类 UnityEditor.Selection public static GameObject activeGameObject public static UnityEng ...

  2. Jmeter关联处理

    采桑子·重阳 人生易老天难老, 岁岁重阳. 今又重阳, 战地黄花分外香. 一年一度秋风劲, 不似春光. 胜似春光, 廖廓江天万里霜. 当请求之间有依赖关系,比如一个请求的入参是另一个请求返回的数据,这 ...

  3. Java SE练习题——求奇数

    欢迎来到Java SE练习题频道,我是Fishing,今天我带来的练习题是(做题会有不足之处,可评论,说出更好的方法): 通过键盘输入两个整数,计算这两个整数之间的所有奇数之和,并输出计算结果. 看到 ...

  4. Tomcat源码学习(3)—— Digester介绍

    Digester方法详解: 通读Digester之前先分析下他的结构: 1.1该类继承了方法DefaultHandler2,DefaultHandler2继承了DefaultHandler是和sax解 ...

  5. JavaScript学习(1)之JavaScript基础

    JavaScript学习(1)之JavaScript基础 由于工作原因,开发语言逐渐以JavaScript为主,所以,抽空学习了下JavaScript语法.等现阶段的工作稳定之后,陆续会分享下自己在学 ...

  6. Python之并发编程-协程

    目录 一.介绍 二. yield.greenlet.gevent介绍 1.yield 2.greenlet 3.gevent 一.介绍 协程:是单线程下的并发,又称微线程,纤程.英文名Coroutin ...

  7. Invalid bound statement (not found): com.example.managerdemo.mapper.SingleTableMapper.selectAllValuesByConditionsNoPage

    报Invalid bound statement (not found): com.example.managerdemo.mapper.SingleTableMapper.selectAllValu ...

  8. 安装Visual studio 2013并进行单元测试

    刚开始在没有老师的指导下自己弄了一个简单的单元测试,最后与老师的对比发现错误百出,于是另起一篇.安装VS2013没有什么问题,安装过程如下图: 接下来别开始练习书上的单元测试. 先是简单的创建C#的类 ...

  9. Scrum Meeting 2 -2014.11.2

    今天大家读完代码后又聚在了一块讨论了许多.确定了重点的任务和分工细节.提出了许多问题和改进的方案.还有讨论分析了关于团队作业 - 软件分析和用户需求调查,初步决定目标软件为必应的输入法和词典,团队为争 ...

  10. 【Alpha发布】贡献分分配

    最后贡献分分配: (1211)王嘉豪:32 (1186)黄雨萌:36 (1182)佘彦廷:40 (1208)何小松:50 (1200)鲁聃:62 (1174)邢浩:64 (1193)刘乾:66