USACO Section 2.1 Ordered Fractions 解题报告
题目
题目描述
给定一个数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 解题报告的更多相关文章
- USACO Section2.1 Ordered Fractions 解题报告
frac1解题报告 —— icedream61 博客园(转载请注明出处)---------------------------------------------------------------- ...
- USACO Section 1.3 Prime Cryptarithm 解题报告
题目 题目描述 牛式的定义,我们首先需要看下面这个算式结构: * * * x * * ------- * * * <-- partial product 1 * * * <-- parti ...
- USACO Section 1.4 Arithmetic Progressions 解题报告
题目 题目描述 现在给你一个数集,里面的数字都是由p^2+q^2这种形式构成的0 <= p,q <= M,我现在需要你在其中找出一个长为N的等差数列,数列中的第一个数字为a,公差为b,当你 ...
- USACO Section 1.3 Combination Lock 解题报告
题目 题目描述 农夫John的牛从农场逃脱出去了,所以他决定用一个密码锁来把农场的门锁起来,这个密码锁有三个表盘,每个表盘都是环形的,而且上面刻有1~N,现在John设了一个开锁密码,而且这个锁的设计 ...
- USACO Section 1.3 Barn Repair 解题报告
题目 题目描述 某农夫有一个养牛场,所有的牛圈都相邻的排成一排(共有S个牛圈),每个牛圈里面最多只圈养一头牛.有一天狂风卷积着乌云,电闪雷鸣,把牛圈的门给刮走了.幸运的是,有些牛因为放假,所以没在自己 ...
- USACO Section 1.3 Mixing Milk 解题报告
题目 题目描述 Merry Milk Makers 公司的业务是销售牛奶.它从农夫那里收购N单位的牛奶,然后销售出去.现在有M个农夫,每个农夫都存有一定量的牛奶,而且每个农夫都会有自己的定价.假设所有 ...
- USACO Section 1.2 Dual Palindromes 解题报告
题目 题目描述 有一些数(如 21),在十进制时不是回文数,但在其它进制(如二进制时为 10101)时就是回文数. 编一个程序,从文件读入两个十进制数N.S.然后找出前 N 个满足大于 S 且在两种以 ...
- USACO Section 1.2 Palindromic Squares 解题报告
题目 题目描述 输入一个基数B,现在要从1到300之间找出一些符合要求的数字N.如果N的平方转换成B进制数之后是一个回文串,那么N就符合要求.我们将N转换成B进制数输出,然后再将N的平方转换成B进制数 ...
- USACO Section 1.2 Milking Cows 解题报告
题目 题目描述 有3个农夫每天早上五点钟便起床去挤牛奶,现在第一个农夫挤牛奶的时刻为300(五点钟之后的第300个分钟开始),1000的时候结束.第二个农夫从700开始,1200结束.最后一个农夫从1 ...
随机推荐
- 二、Unity Editor模式下,操作选中对象
使用Unity提供的工具类 UnityEditor.Selection public static GameObject activeGameObject public static UnityEng ...
- Jmeter关联处理
采桑子·重阳 人生易老天难老, 岁岁重阳. 今又重阳, 战地黄花分外香. 一年一度秋风劲, 不似春光. 胜似春光, 廖廓江天万里霜. 当请求之间有依赖关系,比如一个请求的入参是另一个请求返回的数据,这 ...
- Java SE练习题——求奇数
欢迎来到Java SE练习题频道,我是Fishing,今天我带来的练习题是(做题会有不足之处,可评论,说出更好的方法): 通过键盘输入两个整数,计算这两个整数之间的所有奇数之和,并输出计算结果. 看到 ...
- Tomcat源码学习(3)—— Digester介绍
Digester方法详解: 通读Digester之前先分析下他的结构: 1.1该类继承了方法DefaultHandler2,DefaultHandler2继承了DefaultHandler是和sax解 ...
- JavaScript学习(1)之JavaScript基础
JavaScript学习(1)之JavaScript基础 由于工作原因,开发语言逐渐以JavaScript为主,所以,抽空学习了下JavaScript语法.等现阶段的工作稳定之后,陆续会分享下自己在学 ...
- Python之并发编程-协程
目录 一.介绍 二. yield.greenlet.gevent介绍 1.yield 2.greenlet 3.gevent 一.介绍 协程:是单线程下的并发,又称微线程,纤程.英文名Coroutin ...
- Invalid bound statement (not found): com.example.managerdemo.mapper.SingleTableMapper.selectAllValuesByConditionsNoPage
报Invalid bound statement (not found): com.example.managerdemo.mapper.SingleTableMapper.selectAllValu ...
- 安装Visual studio 2013并进行单元测试
刚开始在没有老师的指导下自己弄了一个简单的单元测试,最后与老师的对比发现错误百出,于是另起一篇.安装VS2013没有什么问题,安装过程如下图: 接下来别开始练习书上的单元测试. 先是简单的创建C#的类 ...
- Scrum Meeting 2 -2014.11.2
今天大家读完代码后又聚在了一块讨论了许多.确定了重点的任务和分工细节.提出了许多问题和改进的方案.还有讨论分析了关于团队作业 - 软件分析和用户需求调查,初步决定目标软件为必应的输入法和词典,团队为争 ...
- 【Alpha发布】贡献分分配
最后贡献分分配: (1211)王嘉豪:32 (1186)黄雨萌:36 (1182)佘彦廷:40 (1208)何小松:50 (1200)鲁聃:62 (1174)邢浩:64 (1193)刘乾:66