5 条题解
-
3
#include <bits/stdc++.h> using namespace std; string a,b;int a1[20],b1[20]; int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); cin>>a>>b; for(int i=0;i<a.size();i++)a1[a[i]-48]++; for(int i=0;i<b.size();i++)b1[b[i]-48]++;//输入+计数 string x=a,y=b;int ans=0; for(int u=1;u<=9;u++)for(int v=1;v<=9;v++) { if(!a1[u]||!b1[v]||u+v<10)continue;//确保肯定能产生一次进位,从而达到最优 string A,B; A='0'+u;B='0'+v;//开始构造,注意转字符串时加上'0' int ca[20],cb[20]; copy(a1,a1+10,ca);copy(b1,b1+10,cb); ca[u]--;cb[v]--;//把最开始配对的减去,注意以后还要构造,所以新开两数组 int res=1;//ans表示以前情况的最大进位数量,res表示此次进位数量 for(int s=9;s<=18;s++)for(int i=1;i<=9;i++) { while(1<=s-i&&s-i<=9&&ca[i]&&cb[s-i]) { ca[i]--;cb[s-i]--; A+=i+'0';B+=s-i+'0'; res++; } } /* 这一部分枚举目标和,两个一位数的和可能范围是 2~18,但为了进位最优,必须≥10, 但第一对数已经产生进位,所以 s可以从 9开始 内层循环i从 1到 9找ca[i]和cb[s-i]是否都有数字,如果有就配一对,加到结果末尾。 这一步贪心:按 s从小到大,尽可能多地配对数字,这样能最大化总对数. */ for(int i=9;i>=1;i--) { res+=(i==9)*(ca[i]+cb[i]); while(ca[i]--)A+=i+'0'; while(cb[i]--)B+=i+'0'; } //剩余数字按升序追加到A和B尾,注意i=9时也算进位,因为前面的数进位加到这也会产生新的进位 reverse(A.begin(),A.end()); reverse(B.begin(),B.end());//记得反过来 if(res>ans) { ans=res; x=A;y=B; }//比较最优 } cout<<x<<'\n'<<y; return 0; } -
3
#include<bits/stdc++.h> using namespace std; const int N=1e5+10; string s;stack<int>b; int l1,l2,a[N],sum[10]; void print() { for(int i=1;i<10;i++) while(sum[i]>0) { printf("%d",i); sum[i]--; } while(b.size()) { printf("%d",b.top()); b.pop(); } exit(0); } int main() { getline(cin,s);l1=s.size(); for(int i=0;i<l1;i++)a[i+1]=s[i]-'0'; getline(cin,s);l2=s.size(); for(int i=0;i<l2;i++)sum[s[i]-'0']++;//sum存储b中数字1至9出现的数量 bool book=0;sort(a+1,a+l1+1);//a排序 for(int i=1;i<=l1;i++)printf("%d",a[i]); puts("");//每次进位数字和会减少,因此从a的末尾开始一直凑进位 for(int i=10-a[l1];i<10;i++)//末尾要凑10,特判 if(sum[i]>0){b.push(i);sum[i]--;book=1;break;} if(!book)print();//如果不能凑出进位,随便填 for(int i=l1-1;i>0;i--) { book=0; for(int j=9-a[i];j<10;j++)//末位进了位,凑9就行 if(sum[j]>0){b.push(j);sum[j]--;book=1;break;} if(!book)print();//同32行 } print();return 0; } -
2
#include<bits/stdc++.h> using namespace std; #define int long long int sum1[15],sum2[15]; string s1,s2; struct node{ int x,y,v; }; vector<node>v[2]; void check(){ for(int i=1;i<=9;i++)if(sum1[i]){ for(int j=10-i;j<=9;j++){ if(sum2[j])return; } } cout<<s1<<'\n'<<s2;//无论如何都无法进位 exit(0); } vector<int>ans1,ans2; signed main(){ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); cin>>s1>>s2; for(int i=0;i<s1.size();i++){ sum1[s1[i]-'0']++; } for(int i=0;i<s2.size();i++){ sum2[s2[i]-'0']++; } check(); for(int i=1;i<=9;i++){ int vv=min(sum1[i],sum2[9-i]); v[0].push_back({i,9-i,vv}); sum1[i]-=vv,sum2[9-i]-=vv; } for(int i=1;i<=9;i++){ for(int j=10-i;j<=9;j++){ int vv=min(sum1[i],sum2[j]); if(!vv)continue; v[1].push_back({i,j,vv}); sum1[i]-=vv,sum2[j]-=vv; } } if(!v[1].size()){ for(int i=0;i<v[0].size();i++){ int x=v[0][i].x,y=v[0][i].y,vv=v[0][i].v; if(!vv)continue; bool bk=0; for(int j=1;x+j<=9;j++)if(x+y+j>=10&&sum1[x+j]){ v[0][i]={x,y,vv-1}; v[1].push_back({x+j,y,1}); sum1[x]++; sum1[x+j]--; bk=1; break; } if(bk)break; for(int j=1;y+j<=9;j++)if(x+y+j>=10&&sum2[y+j]){ v[0][i]={x,y,vv-1}; v[1].push_back({x,y+j,1}); sum2[y]++; sum2[y+j]--; bk=1; break; } if(bk)break; } } for(int i=1;i<=9;i++){ for(int j=1;j<=sum1[i];j++)cout<<i; } for(node i:v[0]){ for(int j=1;j<=i.v;j++)cout<<i.x; } for(node i:v[1]){ for(int j=1;j<=i.v;j++)cout<<i.x; } cout<<'\n'; for(int i=1;i<=9;i++){ for(int j=1;j<=sum2[i];j++)cout<<i; } for(node i:v[0]){ for(int j=1;j<=i.v;j++)cout<<i.y; } for(node i:v[1]){ for(int j=1;j<=i.v;j++)cout<<i.y; } return 0; } -
2
首先本题要求两数相加后所得的数各位数字之和最小 怎么样才能做到最小呢? 不妨设sum为原本两数各位数字之和的和,ans为最终答案,x为两数相加之和 为什么ans会比sum小呢? 因为相加时会有进位 每次进位都会使ans减9 所以核心思路为尽量进位 在两数相加的结果中,9为比较特殊的存在 因为如果后面能往前进1的话,9也能接着往前进位 所以我们不妨把所有x中的9放在一起,然后吧10以上的数放在9的后面(其它数随便放) 9的优先级最先 但还有一种特殊情况 万一把9弄完后没有其他数来进位了呢? 所以我们需要特判 */ #include<bits/stdc++.h> using namespace std; int ac[10],bc[10];//ac[i]代表a字符串中"a"的个数,bc同理 int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); string a,b; cin>>a>>b;//输入 int n=a.size(),m=b.size(); for(int i=1;i<=9;i++) { ac[i]=bc[i]=0; } for(int i=0;i<n;i++) { ac[a[i]-'0']++; } for(int i=0;i<m;i++) { bc[b[i]-'0']++; } string a1,b1; a1=b1=""; bool f=0; for(int k=9;k<=18;k++) { for(int i=max(k-9,1);i<=9;i++) { int j=k-i; int x=min(ac[i],bc[j]);//只能贡献较小的数量 if(x) { f|=(k>9);//这里记录一下是否都是9 a1+=string(x,i+'0');//这句话是指在a1后面加入x个"i"; b1+=string(x,j+'0');//同上 ac[i]-=x,bc[j]-=x;//最终减去做贡献的位 } } } if(!f&&a1!=""&&b1!="")//注意这里需要特判a1与b1不为空,可能相加结果既没9也没10以上 { a1=b1="";//初始化 for(int i=1;i<=9;i++) { ac[i]=bc[i]=0; } for(int i=0;i<n;i++) { ac[a[i]-'0']++; } for(int i=0;i<m;i++) { bc[b[i]-'0']++; }//重新计算 int p,t; for(int k=10;k<=18;k++)//从10开始 { if(f) { break; } for(int i=k-9;i<=9;i++) { if(f) { break; } int j=k-i; int x=min(ac[i],bc[j]); if(x) { f=1; p=i; t=j; ac[i]--; bc[j]--; }//只需一个10以上做贡献即可 } } int k=9; for(int i=1;i<=9;i++) { int j=k-i; int x=min(ac[i],bc[j]); if(x) { a1+=string(x,i+'0'); b1+=string(x,j+'0'); ac[i]-=x,bc[j]-=x; } }//把所有的9再次添入a1与b1中 if(p&&t) { a1+=string(1,p+'0'); b1+=string(1,t+'0');//加上做最终进位贡献的数 } } string c,d; for(int i=1;i<=9;i++) { if(ac[i]) { c+=string(ac[i],i+'0');//统计剩余的位 } } for(int i=1;i<=9;i++) { if(bc[i]) { d+=string(bc[i],i+'0');//同上 } } cout<<c<<a1<<endl<<d<<b1;//最终输出 return 0; } -
0
#include<bits/stdc++.h> using namespace std; typedef long long ll; int c1[15],c2[15]; struct N{ int x,y,v; }; vector<N> v[15]; int main(){ ios::sync_with_stdio(0); cin.tie(0); string s1,s2; cin>>s1>>s2; for(char i:s1){ c1[i-'0']++; } for(char i:s2){ c2[i-'0']++; } string a1="",a2=""; for(int k=10;k>=2;k--){ for(int i=0;i<=9;i++){ int vv=min(c1[i],c2[k-i]); v[k].push_back({i,k-i,min(c1[i],c2[k-i])}); c1[i]-=vv;c2[k-i]-=vv; } } for(int i=0;i<=9;i++){ for(int j=0;j<c1[i];j++)cout<<i; } for(int k=2;k<=10;k++){ for(N i:v[k]){ for(int j=0;j<i.v;j++)cout<<i.x; } } cout<<'\n'; for(int i=0;i<=9;i++){ for(int j=0;j<c2[i];j++)cout<<i; } for(int k=2;k<=10;k++){ for(N i:v[k]){ for(int j=0;j<i.v;j++)cout<<i.y; } } return 0; }
- 1
信息
- ID
- 2517
- 时间
- 2000ms
- 内存
- 1024MiB
- 难度
- 8
- 标签
- 递交数
- 53
- 已通过
- 9
- 上传者