第五届“传智杯”全国大学生计算机大赛 程序设计赛道区域赛---B. 莲子的机械动力学

B. 莲子的机械动力学

【具象化题意】
备注:具象化题意和抽象化题意完全等价,可以只选择其中一
份进行阅读。
专攻超统一物理学的莲子,对机械结构的运动颇有了解。如下
图所示,是一个三进制加法计算器的(超简化)示意图。
在这里插入图片描述
一个四位的三进制整数,从低到高位,标为 𝑥1, 𝑥2, 𝑥3, 𝑥4。换
言之,这个数可以写成 𝑥4𝑥3𝑥2𝑥1(3)。把它放在这四个齿轮里,对
应箭头指向的数字就是现在这位的数值。
在这种机械式计算机里,我们通过齿轮的啮合来实现数位间的
连接。通过不同齿轮半径的比例来确定进制。图中所有浅灰色的小
齿轮的半径,比上使用皮带相接的较大齿轮的半径,都是 1: 3。那
么小齿轮每转动一圈,大齿轮就转动 1
3 圈,也就是刚好一个数码
的角度。
于是,我们通过控制齿轮的半径实现了 3 进制的进位。
如果需要实现三进制加法,则只需要在对应数位拨动对应的数
码长度即可。
如下是个例子,实现 1021(3) + 0021(3) = 1112(3)在这里插入图片描述
初始时齿轮的状态如上在这里插入图片描述
把第一个齿轮拨动一个单位长度,变为如上图所示。
在这里插入图片描述
把第二个齿轮拨动两个单位长度,变为如上图所示。读数,得
到结果 1112(3)。
现在莲子设计了如下图所示的机械结构。对于从左往右数的第
𝑖 枚齿轮,它上面的浅色小齿轮与第 𝑖 + 1 枚齿轮上的深色小齿轮
的半径之比为 1: (𝑖 + 2)。也就是说,第 𝑖 枚齿轮每转动 1 圈,
第 𝑖 + 1 枚齿轮转过的角度恰好为它上面的一个数码。
在这里插入图片描述
莲子想要知道,在这样的特别的进制表示下,给定 𝑎, 𝑏,那么
计算出的 𝑎 + 𝑏 的结果是多少。
【抽象化题意】
给定两个长度分别为 𝑛, 𝑚 的整数 𝑎, 𝑏,计算它们的和。
但是要注意的是,这里的 𝑎, 𝑏 采用了某种特殊的进制表示法。
最终的结果也会采用该种表示法。具体而言,从低位往高位数起,
第 𝑖 位采用的是 𝑖 + 1 进制。换言之,相较于十进制下每一位的
「逢 10 进 1」,该种进制下第 𝑖 位是「逢 𝑖 + 1 进 1」。
下图所示,左边是十进制的竖式加法;右边是这种特殊进制的
竖式加法。图中的红色加号表示上一位发生了进位。
输入格式
第一行有两个整数 𝑛, 𝑚,分别表示 𝑎 和 𝑏 的位数。
第二行有 𝑛 个整数,中间用空格隔开,从高到低位描述 𝑎 的
每个数码。
第三行有 𝑚 个整数,中间用空格隔开,从高到低位描述 𝑏 的
每个数码。
输出格式
输出有若干个整数,从高到低位输出 𝑎 + 𝑏 在这种特殊表示
法下的结果。
输入样例 1 输出样例 1
5 4 4 2 1 1 0
3 3 2 1 1
3 2 2 1
输入样例 2 输出样例 2
10 1 10 9 8 7 6 5 4 3 2 1
10 9 8 7 6 5 4 3 2 1
0

数据规模
对于全部数据,保证 1 ≤ 𝑛, 𝑚 ≤ 2 × 10^5,从低位往高位数起
有 𝑎𝑖 ∈ [0, 𝑖],𝑏𝑖 ∈ [0, 𝑖]。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5+10;
LL a[N],b[N],ans[N];
void solve(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    for(int j=1;j<=m;j++) scanf("%lld",&b[j]);
    LL tt = 2,t = 0;
    int i,j;
    for(i=n,j=m;i>0&&j>0;i--,j--){
        t += a[i] + b[j];
        ans[tt] = t % tt;
        t /= tt;
        tt++;
    }
    while(i>0){
        t += a[i];
        ans[tt] = t % tt;
        t /= tt;
        tt++;
        i--;
    }
    while(j>0){
        t += b[j];
        ans[tt] = t % tt;
        t /= tt;
        tt++;
        j--;
    }
    if(t > 0) ans[tt++] = t;
    for(int i=tt-1;i>=2;i--){
        printf("%lld",ans[i]);
        if(i != 2) printf(" ");
    }
    puts("");
}
int main(){
    solve();
    return 0;
}

原创

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值