题解
这道题其实很容易,枚举全部分数并且排序即可。
但是我用优先队列来做了,发现stl的priority_queue超时,然后自己手撸了个heap,
结果把下调写错了,debug了半天,尴尬-。- |||
代码
/*
PROG:frac1
ID:imking022
LANG:C++
*/
#include <iostream>
#include <cstdio>
#include <fstream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
int n,m,k;
typedef struct Node{
int x,y;
float dvd;
Node(int a=0,int b=0):
x(a),y(b) { dvd = (float)a/(float)b; }
}P;
P cot[16000];
bool vis[161][161];
int hod[100];
bool equ(Node &a,Node &b){
if( abs(a.dvd - b.dvd) < 1e-5) return true;
return false;
}
bool cmp2(Node &a,Node &b){
if(equ(a,b)) return a.y > b.y;// spark!!
return a.dvd < b.dvd;
}
void flw(int pos){// 上浮
if(pos<=1) return;
while( pos!=1 && cmp2(cot[pos],cot[pos/2]) ){
swap( cot[pos] , cot[pos/2] );
pos/=2;
}
}
void ins(P &p){// 入堆
cot[k] = p;
flw(k);
k++;
}
P del(){// 出堆
if(k==1) return -1;
P ret = cot[1];
swap(cot[1],cot[k-1]);
k--;
int tar=1,pos=1;
while( 2*pos<k ){// 向下调整!就是这里!
tar = 2*pos;
if(tar+1 < k){ // cmp2 : <
if(cmp2(cot[tar+1], cot[tar])) tar++;
}
if(cmp2(cot[tar],cot[pos])){
swap(cot[tar],cot[pos]);
pos = tar;
}else
break;
}
return ret;
}
int main(void){
freopen("frac1.out","w",stdout);
freopen("frac1.in","r",stdin);
cin>>n;
memset(vis,false,sizeof(vis));
k=1;
P tmp, p = Node(1,n);
ins(p);
vis[1][n] = true;
cout<<"0/1\n";
while(k>1){
tmp = del();
while(k>1 && equ(tmp,cot[1]) ){
if( tmp.x+1 < tmp.y && !vis[tmp.x+1][tmp.y]){
p = Node(tmp.x+1,tmp.y );
ins(p);
vis[tmp.x+1][tmp.y] = true;
}
if(tmp.y-1 > tmp.x && !vis[tmp.x][tmp.y-1]){
p = Node(tmp.x,tmp.y-1) ;
ins(p);
vis[tmp.x][tmp.y-1] = true;
}
tmp = del();
}
if(tmp.y%tmp.x == 0 )
cout<<"1/"<<tmp.y/tmp.x<<endl;
else
cout<<tmp.x<<"/"<<tmp.y<<endl;
if( tmp.x+1 < tmp.y && !vis[tmp.x+1][tmp.y]){
p = Node(tmp.x+1,tmp.y );
ins(p);
vis[tmp.x+1][tmp.y] = true;
}
if(tmp.y-1 > tmp.x && !vis[tmp.x][tmp.y-1]){
p = Node(tmp.x,tmp.y-1) ;
ins(p);
vis[tmp.x][tmp.y-1] = true;
}
}
if(n!=1) cout<<"1/1\n";
return 0;
}