开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情
[传智杯 #5 初赛] B-莲子的机械动力学
题目背景
【题目背景和题目描述的两个题面是完全等价的,您可以选择阅读其中一部分。】
专攻超统一物理学的莲子,对机械结构的运动颇有了解。如下图所示,是一个三进制加法计算器的(超简化)示意图。
一个四位的三进制整数,从低到高位,标为 。换言之,这个数可以写成 。把它放在这四个齿轮里,对应箭头指向的数字就是现在这位的数值。
在这种机械式计算机里,我们通过齿轮的啮合来实现数位间的连接。通过不同齿轮半径的比例来确定进制。图中所有浅灰色的小齿轮的半径,比上使用皮带相接的较大齿轮的半径,都是 。那么小齿轮每转动一圈,大齿轮就转动 圈,也就是刚好一个数码的角度。
于是,我们通过控制齿轮的半径实现了 进制的进位。
如果需要实现三进制加法,则只需要在对应数位拨动对应的数码长度即可。
如下是个例子,实现
初始时齿轮的状态如上。
把第一个齿轮拨动一个单位长度,变为如上图所示。
把第二个齿轮拨动两个单位长度,变为如上图所示。读数,得到结果 。
现在莲子设计了如下图所示的机械结构。对于从左往右数的第 枚齿轮,它上面的浅色小齿轮与第 枚齿轮上的深色小齿轮的半径之比为 。也就是说,第 枚齿轮每转动 圈,第 枚齿轮转过的角度恰好为它上面的一个数码。
莲子想要知道,在这样的特别的进制表示下,给定 ,那么计算出的 的结果是多少。
题目描述
题目背景的问题可以转化为如下描述:
给定两个长度分别为 的整数 ,计算它们的和。
但是要注意的是,这里的 采用了某种特殊的进制表示法。最终的结果也会采用该种表示法。具体而言,从低位往高位数起,第 位采用的是 进制。换言之,相较于十进制下每一位的「逢 进 」,该种进制下第 位是「逢 进 」。
下图所示,左边是十进制的竖式加法;右边是这种特殊进制的竖式加法。图中的红色加号表示上一位发生了进位。
输入格式
- 第一行有两个整数 ,分别表示 和 的位数。
- 第二行有 个整数,中间用空格隔开,从高到低位描述 的每个数码。
- 第三行有 个整数,中间用空格隔开,从高到低位描述 的每个数码。
输出格式
- 输出有若干个整数,从高到低位输出 在这种特殊表示法下的结果。
样例 #1
样例输入 #1
5 4
3 3 2 1 1
3 2 2 1
样例输出 #1
4 2 1 1 0
样例 #2
样例输入 #2
10 1
10 9 8 7 6 5 4 3 2 1
0
样例输出 #2
10 9 8 7 6 5 4 3 2 1
提示
对于全部数据,保证 ,从低位往高位数起有 ,。请使用 Java 或 Python 语言作答的选手注意输入输出时的效率。
分析
这题题目虽然说的很复杂,其实就是一个很简单的高精度加法(简化版的),有一些细节要注意,比如开数组时候要多开一位,最后一位可能会进位qaq
代码
#include <iostream>
#include <string>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <cstring>
#include <stack>
#include <cmath>
#include <algorithm>
#define ll long long
using namespace std;
const int N=201000;
bool st[N*10][2];
int a[N],b[N],c[N],jin[N];
int main(){
int n,m;
cin>>n>>m;
for(int i=n;i;i--) cin>>a[i];
for(int i=m;i;i--) cin>>b[i];
int ma=max(m,n);
// for(int i=ma;i;i--) cout<<a[i]<<" ";
// cout<<"\n";
// for(int i=ma;i;i--) cout<<b[i]<<" ";
for(int i=1;i<=ma;i++){
if(a[i]+b[i]+jin[i-1]>i){
c[i]=(a[i]+b[i]+jin[i-1])%(i+1);
}
else c[i]=a[i]+b[i]+jin[i-1];
jin[i]=(a[i]+b[i]+jin[i-1])/(i+1);
}
if(jin[ma]!=0) cout<<jin[ma]<<" ";
for(int i=ma;i;i--){
cout<<c[i]<<" ";
}
return 0;
}
希望能帮助到大家()!