基本思路是受到了M路归并的启发。
从这里也看得出来基础的重要性。
/*
ID: fairyroad
TASK: frac1
LANG:C++
*/
#include<fstream>
#include<algorithm>
using namespace std;
ifstream fin("frac1.in");
ofstream fout("frac1.out");
#define LEN 160
int n;
struct fraction{
int up, down;
fraction() : up(0), down(0) {}
fraction(int a, int b) : up(a), down(b) {}
};
fraction fs[LEN];
inline bool comp(const fraction& f1, const fraction& f2 ){
return f1.up * f2.down > f1.down * f2.up;
}
bool check(int a, int b){ // relatively prime or not
int t;
if(a < b){ t = a; a = b; b = t;}
while(t = a%b) {
a = b;
b = t;
}
return b == 1 ? true : false;
}
inline void print(const fraction& f) { fout<<f.up<<"/"<<f.down<<"\n"; }
int main()
{
fin>>n;
print(fraction(0, 1));
int i;
for(i = 1; i < n; ++i){
int t = n;
while(!check(i,t)) --t;
fs[i-1] = fraction(i, t);
}
make_heap(fs, fs+n-2, comp);
int size = n-1, j;
while(fs[0].up!=n-1)
{
print(fs[0]);
pop_heap(fs, fs+size, comp);
bool flag = false;
for(j = fs[size-1].down-1; j > fs[size-1].up; --j) // M路归并的思路就体现在这里了
if(check(fs[size-1].up, j)){
fs[size-1] = fraction(fs[size-1].up, j);
flag = true;
break;
}
if(!flag) --size;
push_heap(fs, fs+size, comp);
}
if(size != 0)print(fs[0]);
print(fraction(1,1));
return 0;
}