結果
| 問題 |
No.81 すべて足すだけの簡単なお仕事です。
|
| コンテスト | |
| ユーザー |
@abcde
|
| 提出日時 | 2019-05-12 00:59:16 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 2 ms / 5,000 ms |
| コード長 | 6,202 bytes |
| コンパイル時間 | 1,867 ms |
| コンパイル使用メモリ | 174,140 KB |
| 実行使用メモリ | 5,376 KB |
| 最終ジャッジ日時 | 2024-07-22 16:47:01 |
| 合計ジャッジ時間 | 2,867 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 30 |
ソースコード
// 改善版.
#include <bits/stdc++.h>
using namespace std;
int main() {
// 1. 入力情報取得.
int N;
cin >> N;
// 2. 加算.
// ex.
// 10
// -9999999999.9999999999
// -9999999999.9999999999
// -9999999999.9999999999
// -9999999999.9999999999
// -9999999999.9999999999
// -9999999999.9999999999
// -9999999999.9999999999
// -9999999999.9999999999
// -9999999999.9999999999
// -9999999999.9999999999
// -> -99999999999.9999928325 は, WAのはず.
// -> 小数点よりも左側, 右側 を分けて計算する方針に変更.
long long lAns = 0, rAns = 0;
for(int i = 0; i < N; i++){
string s;
cin >> s;
// 2-1. 符号取得.
char sign = s[0];
int pos = s.find(".");
// 2-2. ピリオドある場合, 前半, 後半に分割.
if(pos != string::npos){
string l = s.substr(0, pos);
string r = s.substr(pos + 1, s.size() - pos - 1);
while(r.size() < 10) r += '0';
lAns += stod(l);
if(sign == '-') rAns -= stod(r);
else rAns += stod(r);
// cout << "l=" << l << " r=" << r << " lAns=" << lAns << " rAns=" << rAns << endl;
}
// 2-3. ピリオドが無い場合.
if(pos == string::npos) lAns += stod(s);
}
// 3. 編集.
// 合計値: lAns, rAns の 値をベース に 編集.
char rSign = (rAns >= 0) ? '+' : '-';
char lSign = (lAns >= 0) ? '+' : '-';
string slAns = to_string(lAns);
string srAns = to_string(rAns);
if(lSign == '-') slAns.erase(slAns.begin());
if(rSign == '-') srAns.erase(srAns.begin());
while(srAns.size() < 10) srAns = '0' + srAns;
lAns = abs(lAns);
rAns = abs(rAns);
// 3-1. (lAns >= 0 && rAns >= 0) もしくは (lAns <= 0 && rAns <= 0) の 場合.
if((lSign == '+' && rSign == '+') || (lSign == '-' && rSign == '-')){
string srExAns = (srAns.size() > 10) ? srAns.substr(0, srAns.size() - 10) : "";
string srResAns = srAns.substr(srAns.size() - 10, 10);
long long rExAns = (srExAns.size() > 0) ? stod(srExAns) : 0;
lAns += rExAns;
srAns = srResAns;
if(lSign == '+') slAns = (lAns == 0) ? "0" : to_string(lAns);
if(lSign == '-') slAns = (lAns == 0) ? "-0" : ('-' + to_string(lAns));
// cout << "3-1. slAns=" << slAns << " srAns=" << srAns << endl;
}
// 3-2. lAns >= 0, rAns < 0 の 場合.
if(lSign == '+' && rSign == '-'){
string srExAns = (srAns.size() > 10) ? srAns.substr(0, srAns.size() - 10) : "";
string srResAns = srAns.substr(srAns.size() - 10, 10);
long long rExAns = (srExAns.size() > 0) ? stod(srExAns) : 0;
long long rResAns = (srResAns.size() > 0) ? stod(srResAns) : 0;
if(lAns > rExAns){
lAns -= rExAns;
lAns--;
rAns = 1e10 - rResAns;
// -> 以下のテストケースで, WAとなった.
// 99_system_test3.txt: -481.10000000000
// 99_system_test4.txt: -71.10000000000
// -> そもそも, rAns は, 10桁 を 想定しているのに, 上記テストケースで,
// 11桁(10000000000)で, 返されたことが分かる.
if(rAns == 1e10) lAns++, rAns = 0;
// ex. 1 -> 0000000001 へ変換.
srResAns = to_string(rAns);
while(srResAns.size() < 10) srResAns = '0' + srResAns;
srAns = srResAns;
if(lAns == 0) slAns = "0";
else slAns = to_string(lAns);
}else{
rExAns -= lAns;
// 6
// -0.9999999999
// -0.9999999999
// -0.9999999999
// -0.9999999999
// -0.9999999999
// 1
// -> -3.9999999995 にならなかった.
// bug.
// lAns = 0;
lAns = rExAns;
while(srResAns.size() < 10) srResAns = '0' + srResAns;
srAns = srResAns;
if(lAns == 0) slAns = slAns = "-0";
else slAns = ("-" + to_string(lAns));
}
// cout << "3-2. slAns=" << slAns << " srAns=" << srAns << endl;
}
// 3-3. lAns < 0, rAns >= 0 の 場合.
if(lSign == '-' && rSign == '+'){
string srExAns = (srAns.size() > 10) ? srAns.substr(0, srAns.size() - 10) : "";
string srResAns = srAns.substr(srAns.size() - 10, 10);
long long rExAns = (srExAns.size() > 0) ? stod(srExAns) : 0;
long long rResAns = (srResAns.size() > 0) ? stod(srResAns) : 0;
if(lAns > rExAns){
lAns -= rExAns;
lAns--;
rAns = 1e10 - rResAns;
// -> 以下のテストケースで, WAとなった.
// 99_system_test3.txt: -481.10000000000
// 99_system_test4.txt: -71.10000000000
// -> そもそも, rAns は, 10桁 を 想定しているのに, 上記テストケースで,
// 11桁(10000000000)で, 返されたことが分かる.
if(rAns == 1e10) lAns++, rAns = 0;
// ex. 1 -> 0000000001 へ変換.
srResAns = to_string(rAns);
while(srResAns.size() < 10) srResAns = '0' + srResAns;
srAns = srResAns;
if(lAns == 0) slAns = "-0";
// 以下のテストケースで, WA版となったので, 修正.
// 04.txt: -09999999999.9999999999
// 99_system_test3.txt: -0481.10000000000
// 99_system_test4.txt: -071.10000000000
// system_test2.txt: -034600561.4230961320
// else slAns = ("-0" + to_string(lAns));
else slAns = ("-" + to_string(lAns));
}else{
rExAns -= lAns;
lAns = 0;
while(srResAns.size() < 10) srResAns = '0' + srResAns;
srAns = srResAns;
slAns = to_string(rExAns);
}
// cout << "3-3. slAns=" << slAns << " srAns=" << srAns << endl;
}
// 4. 出力.
cout << slAns << "." << srAns << endl;
return 0;
}
@abcde