有理数的个数

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

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

CYH

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;


}
  


 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值