提出 #47412428
ソースコード 拡げる
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
vector a(2, vector<ll>(0));
vector l(2, vector<ll>(0));
vector<ll> sm(2);
// 入力
for (int num=0; num<2; num++){
int m; cin >> m;
a[num].resize(m);
l[num].resize(m);
for (int i=0; i<m; i++){
cin >> a[num][i] >> l[num][i];
sm[num] += l[num][i];
}
reverse(a[num].begin(), a[num].end());
reverse(l[num].begin(), l[num].end());
}
// 0埋め
if (sm[0] < sm[1]){
a[0].push_back(0);
l[0].push_back(sm[1] - sm[0]);
}
if (sm[0] > sm[1]){
a[1].push_back(0);
l[1].push_back(sm[0] - sm[1]);
}
// 区間の長さの代わりに累積和(何桁目で数字が変わるか)を使う
for (int num=0; num<2; num++){
for (int i=0; i<(int)l[num].size()-1; i++){
l[num][i+1] += l[num][i];
}
}
// 足し算の処理
int p0 = 0, p1 = 0;
ll now = 0;
vector<ll> ansa;
vector<ll> ansl;
ll val0 = a[0][0], val1 = a[1][0];
bool carry = 0;
ll nxt0 = l[0][0], nxt1 = l[1][0];
while (p0 < (int)l[0].size() || p1 < (int)l[1].size()){
bool something_new = 0; // 位の数字が変化したか?
if (now == 0) something_new = 1;
// A の位の数字が変化した場合
if (p0 < (int)l[0].size() && now >= l[0][p0]){
p0++;
if (p0 < (int)l[0].size()){
nxt0 = l[0][p0];
val0 = a[0][p0];
}else{
break;
}
something_new = 1;
}
// B の位の数字が変化した場合
if (p1 < (int)l[1].size() && now >= l[1][p1]){
p1++;
if (p1 < (int)l[1].size()){
nxt1 = l[1][p1];
val1 = a[1][p1];
}else{
break;
}
something_new = 1;
}
// 足し算
ll t;
if (carry){
t = val0 + val1 + 1;
}else{
t = val0 + val1;
}
if (t >= 10){
carry = true;
}else{
carry = false;
}
if (something_new){
// 桁の数字が変化した場合
ansa.push_back(t % 10);
ansl.push_back(1);
now++;
}else{
// 区間をまとめて処理
ansa.push_back(t % 10);
ansl.push_back(min(nxt0, nxt1) - now);
now = min(nxt0, nxt1);
}
}
// 最上位が繰り上がりだった場合
if (carry){
ansa.push_back(1);
ansl.push_back(1);
}
// 答えの生成 (ランレングス圧縮)
vector<ll> reta;
vector<ll> retl;
for (int i=0; i<(int)ansa.size(); i++){
assert (ansl[i] > 0);
reta.push_back(ansa[i]);
retl.push_back(ansl[i]);
if ((int)reta.size() >= 2 && reta[(int)reta.size() - 1] == reta[(int)reta.size() - 2]){
reta.pop_back();
retl[(int)retl.size() - 2] += retl[(int)retl.size() - 1];
retl.pop_back();
}
}
reverse(reta.begin(), reta.end());
reverse(retl.begin(), retl.end());
// 出力
int m = reta.size();
cout << m << '\n';
for (int i=0; i<m; i++){
cout << reta[i] << ' ' << retl[i] << '\n';
}
}
提出情報
| 提出日時 | |
|---|---|
| 問題 | aplusb - 足し算 (a + b problem) |
| ユーザ | shobonvip |
| 言語 | C++ 20 (gcc 12.2) |
| 得点 | 100 |
| コード長 | 2875 Byte |
| 結果 | AC |
| 実行時間 | 21 ms |
| メモリ | 6460 KiB |
ジャッジ結果
| セット名 | Set01 | Set02 | Set03 | Set04 | Set05 | Set06 | Set07 | Set08 | Set09 | Set10 | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 得点 / 配点 | 10 / 10 | 10 / 10 | 10 / 10 | 10 / 10 | 10 / 10 | 10 / 10 | 10 / 10 | 10 / 10 | 10 / 10 | 10 / 10 | ||||||||||||||||||||
| 結果 |
|
|
|
|
|
|
|
|
|
|
| セット名 | テストケース |
|---|---|
| Set01 | 01 |
| Set02 | 02 |
| Set03 | 03 |
| Set04 | 04 |
| Set05 | 05 |
| Set06 | 06 |
| Set07 | 07 |
| Set08 | 08 |
| Set09 | 09 |
| Set10 | 10 |
| ケース名 | 結果 | 実行時間 | メモリ |
|---|---|---|---|
| 01 | AC | 4 ms | 3560 KiB |
| 02 | AC | 2 ms | 3700 KiB |
| 03 | AC | 2 ms | 3576 KiB |
| 04 | AC | 11 ms | 4796 KiB |
| 05 | AC | 10 ms | 4880 KiB |
| 06 | AC | 16 ms | 5328 KiB |
| 07 | AC | 15 ms | 5104 KiB |
| 08 | AC | 13 ms | 4600 KiB |
| 09 | AC | 20 ms | 6460 KiB |
| 10 | AC | 21 ms | 6396 KiB |