Ordered Fractions(二叉搜索树)
题意:输入一个n,按从小到大的顺序输出从0到1之间的所有分母不大于n的最简分数。
比较容易想到的是排序。可以用结构体表示一个分数,将所有符合条件的分数都存到数组里,然后sort一下,输出就行。注意cmp函数的写法
bool cmp(node x,node y) { return x.a*y.b<x.b*y.a; //比较两个分数的大小,交叉相乘 }
最近刚学了二叉树,可以用二叉查找树,实现插入排序。
0/1和1/1这两个值只能逼近不能达到,直接输出即可。
根据二叉查找树的性质,显然1/2是该树的head。
然后分子分母从小到大,往树里进行插入。如果发现树中已有相同的值,说明该分数不是最简,而且已经有最简的在树里了,直接pass掉这个分数即可。
最后,中序遍历输出即可。
#include <cstdio> #include <cstring> using namespace std; struct Node { int up; int down; Node *left; Node *right; Node *p; Node() { left=NULL; right=NULL; p=NULL; } }*head; void Insert(Node* t) { Node *th; th=head; Node* y; y=NULL; while(th!=NULL) { y=th; if(t->up*th->down>t->down*th->up) { th=th->right; } else if(t->up*th->down==t->down*th->up) { return; //相同元素,说明不是最简分数,并且前面肯定出现过了。 } else th=th->left; } t->p=y; //让t的p指针指向y if(y==NULL)//如果树为空。本题不用考虑。 { head=t; } else if(t->up*y->down > t->down*y->up) //把待插结点,插在y的下面(让y指向t)。 { y->right=t; } else y->left=t; } void inorder(Node* head) { Node* th; th=head; if(th!=NULL) { inorder(th->left); printf("%d/%d\n",th->up,th->down); inorder(th->right); } } int main() { int n; while(scanf("%d",&n)!=EOF) { printf("0/1\n"); if(n==1) { printf("1/1\n\n"); continue; } head=new Node(); head->up=1; head->down=2; for(int i=2; i<=n; i++) { for(int j=1; j<i; j++) { Node *t; t=new Node(); t->up=j; t->down=i; Insert(t); } } inorder(head); printf("1/1\n\n"); } return 0; }