Font Size:
←
→
Problem Description
任何一个有理数都可以表示成M/N的形式(M,N均为正整数)。例如1/2,2/4,3/6都是等值的有理数。给定若干有理数,等值有理数的值只能算一个,问这些有理数含有多少个值,并按从小到大输出各值及该值的有理数个数。
Input
第一行是整数n,表示随后有n组测试数据(n不超过10)。
每一组测试数据的第一行是一个整数m(m<=100000),随后有m行,每一行都是A/B的形式, 1<=A,B<=1000000000
每一组测试数据的第一行是一个整数m(m<=100000),随后有m行,每一行都是A/B的形式, 1<=A,B<=1000000000
Output
对于每一组测试数据,输出要求如下,第一行输出有理数值的个数p,随后的p行按从小到大的次序每一行输出一个A/B形式的值及其对应的有理数个数,用空格分开,要求A/B是最简分数。
Sample Input
2 2 1/3 1/4 4 1/1 1/2 7/14 7/7
Sample Output
2 1/4 1 1/3 1 2 1/2 2 1/1 2
Author
Source
#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
struct node{
int a;
int b;
double res;
}stu[100000];
int gcd(int a,int b)
{
int t,r;
if(a<b)
{t=b;
b=a;
a=t;
}
while((r=a%b)!=0)
{r=a%b;
a=b;
b=r;}
return b;
}
bool cmp(node x,node y)
{
return x.res<y.res; // res=a/b 按res的升序
}
int main()
{
int c[100000],d[100000];
int a,b,i,j,k,n,m;
scanf("%d",&n);
while(n--)
{
scanf("%d",&m);
for(i=0;i<m;i++)//输入数据
scanf("%d/%d",&stu[i].a,&stu[i].b);
for(i=0;i<m;i++)//化简
{
a=gcd( stu[i].a,stu[i].b);
stu[i].a/=a;
stu[i].b/=a;
stu[i].res=stu[i].a*1.0/stu[i].b; // *1.0将int变double
}
sort(stu,stu+m,cmp);
for(i=0,j=0,k=0,c[0]=1;i<m;i++)
{
if(stu[i].a==stu[i+1].a&&stu[i].b==stu[i+1].b)
{
c[j]++;
}
else
{ d[j]=i;//记下不同有理数的下标
j++;
c[j]=1;//记录相同有理数的个数
k=j; //k为不同有理数的个数
}
}
c[j]='\0';
printf("%d\n",k);
for(i=0;c[i]!='\0';i++) //输出
printf("%d/%d %d\n",stu[d[i]].a,stu[d[i]].b,c[i]);
}
return 0;
}