USACO Ordered Fractions
2290 ワード
私の考え:すべての点数を列挙して、それが最も簡単かどうかを判断して(分母分子の最大公約数=1)、1つの数列ですべての最も簡単な点数を記録して、それから速い列で並べ替えます.
他にも考えられます
1.
任意の2つの点数の差は一定>=1/(160*159)であるため、すべての点数を直接50880に乗じ、四捨五入して直接バケツソートし、入力しながら並べ、分子分母を同時に記録するだけでよい、O(n)!!簡略化も省けたので、同じ値に遭遇したらスキップします(以前は必ずもっと小さい点数がこの値に等しいからです).
2.明らかに、0/i 1/i 2/i...i/iこのシーケンスは、n個のシーケンスを秩序化して集計すればよい(等しければ分母の最小の1つをとる--これは明らかに最も単純な点数である).
/*
ID: wangxin12
PROG: frac1
LANG: C++
*/
#include
#include
#include
#include
#include
using namespace std;
class Fraction {
public:
int numerator;
int denominator;
};
int N;
int GCD(int a, int b) {
//Euclidean Algo
if(a < b) return GCD(b, a);
if(b == 0) return a;
else return GCD(b, a % b);
/*
int r = a % b;
if(r == 0) return b;
else return GCD(b ,r);
*/
}
vector result;
bool Cmp(Fraction & a, Fraction & b) {
if( a.numerator * b.denominator >= a.denominator * b.numerator ) return true;
else return false;
}
template
int Partition(vector & f, int start, int finish, bool (cmp)(T & a, T & b)) {
T key = f[start];
int left = start + 1;
int right = finish;
while(true) {
while(right > left && cmp(f[right],key)) right--;
while(left < right && !cmp(f[left],key)) left++;
if(left == right) break;
T temp = f[left];
f[left] = f[right];
f[right] = temp;
}
if(cmp(f[left],key)) return start;
f[start] = f[left];
f[left] = key;
return left;
}
template
void QuickSort(vector & f, int start, int finish) {
if(start >= finish) return;
int boundary = Partition(f, start, finish, Cmp);
QuickSort(f, start, boundary - 1);
QuickSort(f, boundary + 1, finish);
}
int main() {
ifstream fin("frac1.in");
fin>>N;
fin.close();
for(int i = 1; i <= N; i++) {
for(int j = 0; j <= i; j++) {
if(GCD(j, i) == 1) {
Fraction t;
t.numerator = j;
t.denominator = i;
result.push_back(t);
}
}
}
QuickSort(result, 0, result.size() - 1);
//
ofstream fout("frac1.out");
for(int k = 0; k < result.size(); k++) {
fout<
他にも考えられます
1.
任意の2つの点数の差は一定>=1/(160*159)であるため、すべての点数を直接50880に乗じ、四捨五入して直接バケツソートし、入力しながら並べ、分子分母を同時に記録するだけでよい、O(n)!!簡略化も省けたので、同じ値に遭遇したらスキップします(以前は必ずもっと小さい点数がこの値に等しいからです).
2.明らかに、0/i 1/i 2/i...i/iこのシーケンスは、n個のシーケンスを秩序化して集計すればよい(等しければ分母の最小の1つをとる--これは明らかに最も単純な点数である).