JZOJ__Day 2:【NOIP普及模拟】分数

本文介绍了一道算法题目,任务是计算两组玩偶默契值的既约分数比。默契值定义为玩偶权值的乘积。文章提供了完整的程序实现,并详细解释了如何通过质因数分解来简化计算过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述
ProKing来到了家里,忽然发现桌台上有n1个玩偶,每个玩偶上有一个对应的值,而在桌台下也有n2个玩偶,每个玩偶上也有一个对应的值,现在,
proking想知道台上的玩偶的默契值除以台下玩偶的默契值得到的既约分数(既约分数就是分子分母最大公约数为1的分数)
默契值定义为所有玩偶的权值的乘积.
输入
输入的第一行是一个n1,后面n1个整数,即序列a;输入的第二行是一个n2,后面n2个整数,即序列b
输出
输出一行两个整数,中间用空格隔开,即表示分子和分母
样例输入
3 1 2 3
4 3 5 2 1

Sample Input2
5 4 6 8 3 2
10 1 2 3 4 5 6 7 8 9 10
 
样例输出
1 5

Sample Output2
1 3150


 
数据范围限制
对于20%的数据,n1,n2<=10,Ai,Bi<=10
对于60%的数据,n1,n2<=1000,Ai,Bi<=1000
对于100%的数据,n1,n2<=100000,Ai,Bi<=10000
数据保证不会出现分数的值为0的情况



题意

把上下两排的数分别相乘,上面的数除以下面的数,把它们化为最简分数。



程序:

        

var
n1,n2:int64;
a,s,l:array[0..100101,1..2]of int64;
bz,z,y:int64;
i,j,k:longint;
ss:array[0..12624]of int64;
procedure aa;
var
i,bz1:longint;
begin
    for i:=2 to 10000 do
    begin
        bz1:=0;
        for j:=2 to trunc(sqrt(i)) do
        if (i mod j=0) then
        begin
            ss[i]:=j;
            bz1:=j;
            break;
        end;
        if bz1=0 then ss[i]:=i;
    end;
end;

begin
    read(n1);
    for i:=1 to n1 do
    read(a[i,1]);
    read(n2);
    for i:=1 to n2 do
    read(a[i,2]);
    aa;
    for i:=1 to n1 do
    begin
        bz:=a[i,1];
        while bz>1 do
        begin
            inc(s[ss[bz],1]);
            bz:=bz div ss[bz];
        end;
    end;
    for i:=1 to n2 do
    begin
        bz:=a[i,2];
        while bz>1 do
        begin
            inc(s[ss[bz],2]);
            bz:=bz div ss[bz];
        end;
    end;
    for i:=2 to 10000 do
    if (s[i,1]>0)and(s[i,2]>0) then
    if (s[i,1]>s[i,2]) then
    begin
        s[i,1]:=s[i,1]-s[i,2];
        s[i,2]:=0;
    end else
    begin
        s[i,2]:=s[i,2]-s[i,1];
        s[i,1]:=0;
    end;
    l[2300,1]:=1; l[2300,2]:=1;
    for j:=2 to 10000 do
    begin
        z:=s[j,1];
        while z>0 do
        begin
            dec(z);
            for k:=2 to 2300 do
            l[k,1]:=l[k,1]*j;
            for k:=2300 downto 2 do
            if l[k,1]>9 then
            begin
                l[k-1,1]:=l[k-1,1]+l[k,1] div 100000000;
                l[k,1]:=l[k,1] mod 100000000;
            end;
        end;
    end;
    for j:=2 to 10000 do
    begin
        z:=s[j,2];
        while z>0 do
        begin
            dec(z);
            for k:=2 to 2300 do
            l[k,2]:=l[k,2]*j;
            for k:=2300 downto 2 do
            if l[k,2]>9 then
            begin
                l[k-1,2]:=l[k-1,2]+l[k,2] div 100000000;
                l[k,2]:=l[k,2] mod 100000000;
            end;
        end;
    end;
    bz:=0;
    for i:=1 to 2 do
    begin
        for j:=0 to 2300 do
        if l[j,i]>0 then
        begin
            bz:=j;
            break;
        end;
        write(l[bz,i]);
        for j:=bz+1 to 2300 do
        begin
            y:=l[j,i]; z:=0;
            if y=0 then y:=1;
            while y<100000000 do
            begin
                y:=y*10;
                z:=z+1;
            end;
            for k:=2 to z do write('0');
            write(l[j,i]);
        end;
        write(' ');
    end;
end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值