打卡信奥刷题(3239)用C++实现信奥题 P8482 「HGOI-1」Number
P8482 「HGOI-1」Number
题目背景
bh1234666\text{bh1234666}bh1234666 正在学习乘法!
题目描述
bh1234666\text{bh1234666}bh1234666 有一定数量的数字 0∼90 \sim 90∼9,现在他想让你寻找一种分配方案,将它们分成两个整数,使得他们的乘积 ppp 最大。
由于 bh1234666\text{bh1234666}bh1234666 不喜欢太大的数,所以你只需要输出两个非负整数,使它们的乘积等于最大乘积 ppp,但是这两个整数 0∼90 \sim 90∼9 的数量不能等于给定的数量(任意一个数字数量不相等即可,不考虑前导零)。
bh1234666\text{bh1234666}bh1234666 是很善良的,如果 0∼90 \sim 90∼9 的数量等于给定的数量了,你依旧可以得到的一半的分。
输入格式
第一行十个整数 c0,c1,⋯c9c_0,c_1,\cdots c_9c0,c1,⋯c9,分别表示 0∼90 \sim 90∼9 的个数。
输出格式
共两行每行一个非负整数,分别表示你给出的两个非负整数。
输入输出样例 #1
输入 #1
1 2 3 2 1 1 2 1 2 1
输出 #1
13949030
620572547
说明/提示
样例解释
最大可能乘积为 97643210×88653221=13949030×620572547=865638507527941097643210 \times 88653221=13949030 \times 620572547=865638507527941097643210×88653221=13949030×620572547=8656385075279410。
若输出 97643210×8865322197643210 \times 8865322197643210×88653221 则只能得到一半的分,因为 0∼90\sim 90∼9 出现的次数与给定的相同。
数据范围及约定
本题采用捆绑测试,共有 555 个 subtask\text{subtask}subtask,最终分数为所有 subtask\text{subtask}subtask 分数之和。
TaskScore∑ci≤110202201003205000420106530107 \def\arraystretch{1.5} \begin{array}{|c|c|c|}\hline \textbf{Task} & \textbf{Score} & \sum c_i\le \cr\hline 1 & 10 & 20 \cr\hline 2 & 20 & 100 \cr\hline 3 & 20 & 5000 \cr\hline 4 & 20 & 10^6 \cr\hline 5 & 30 & 10^7 \cr\hline \end{array} Task12345Score1020202030∑ci≤201005000106107
对于 100%100\%100% 的数据,保证 1≤ci1 \le c_i1≤ci,∑ci≤107\sum c_i \le 10^7∑ci≤107。
说明
本题有 spj\text{spj}spj,两数乘积正确得一半的分,数量与给出的不同且乘积正确得全部分数。故每一 subtask\text{subtask}subtask 的得分为其中所有数据点得分的最小值。
C++实现
#include<bits/stdc++.h>
using namespace std;
int c[10],len1,len2,res1[10000001],res2[10000001];
int main(){
for(int i=0;i<10;++i)cin>>c[i];
bool f=0;
int cnt=0;
for(int i=9;~i;--i){
for(int j=0;j<c[i];++j){
++cnt;
if(!f){
if(cnt&1)res1[++len1]=i;
else res2[++len2]=i;
}
else{
if(cnt&1)res2[++len2]=i;
else res1[++len1]=i;
}
if(!f&&len1==len2&&res1[len1]>res2[len2])
f=1;
}
}
int l1=1,l2=1;
if(res1[len1]==0){
for(int i=1;i<=len1;++i){
if(res1[i]&1)res1[i+1]+=10;
res1[i]/=2;
}
if(!res1[1])l1=2;
for(int i=1;i<=len2;++i)res2[i]+=res2[i];
for(int i=len2;i;--i)res2[i-1]+=res2[i]/10,res2[i]%=10;
if(res2[0])l2=0;
}
else if(res2[len2]==0){
for(int i=1;i<=len2;++i){
if(res2[i]&1)res2[i+1]+=10;
res2[i]/=2;
}
if(!res2[1])l2=2;
for(int i=1;i<=len1;++i)res1[i]+=res1[i];
for(int i=1;i<=len1;++i)res1[i+1]+=res1[i]/10,res1[i]%=10;
if(res1[len1+1])l1=0;
}
for(int i=l1;i<=len1;++i)putchar(res1[i]+48);
putchar('\n');
for(int i=l2;i<=len2;++i)putchar(res2[i]+48);
return 0;
}

后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容
更多推荐



所有评论(0)