最佳加法表达式
-
总时间限制:
- 1000ms 内存限制:
- 65536kB
-
描述
-
给定n个1到9的数字,要求在数字之间摆放m个加号(加号两边必须有数字),使得所得到的加法表达式的值最小,并输出该值。例如,在1234中摆放1个加号,最好的摆法就是12+34,和为36
输入
-
有不超过15组数据
每组数据两行。第一行是整数m,表示有m个加号要放( 0<=m<=50)
第二行是若干个数字。数字总数n不超过50,且 m <= n-1
输出
- 对每组数据,输出最小加法表达式的值 样例输入
-
2 123456 1 123456 4 12345
样例输出
-
102 579 15
提示
- 要用到高精度计算,即用数组来存放long long 都装不下的大整数,并用模拟列竖式的办法进行大整数的加法。
-
- 解题思路:因为存在超大数,所以我用了一个数组表示一个数的方法,并且用全局数组ab来放置给定的数据,在digui(int a,int b,int c)函数中a代表当前进行ab数组中a下标,b代表还剩下的“+”,c代表上一个“+”右边的下标,我的递归函数就是已ab数组的长度和m<=n-1为边界,x代表在当前位的后面没有添置“+”,所以直接返回digui(a+1,b,c);y代表当前位后面添置了“+”,因此,y要加上前次“+”到此次“+”之间的数在加上digui(a+1,b-1,a+1)返回。(em.........表示我自己也没十分理清,能不能看懂就看你自己了。)
-
代码如下:
#include <iostream> #include <vector> #include <string> #include <algorithm> using namespace std; //因为存在超大数 所以我用的数组来代替一个数 vector<int> ab; //记录输入数据的素组 vector<int> notPass(52,1);//设置最大数 void coutVector(vector<int> a);//输出数组所有元素就是相当于输出个数字 vector<int> AddBigNum(vector<int> a,vector<int> b);//两个数组型的数字相加 vector<int> digui(int a,int b,int c);//递归函数 bool compare(vector<int> a,vector<int> b);//两个数组型的数字比较大小 vector<vector<vector<vector<int> > > >judge;//递归的备忘录 int main(){ int m; while(cin>>m){ string temp ; cin>>temp; //赋予空间获取数组 ab.resize(temp.size()); judge.resize(temp.size()); int i = 0,j=0,z=0; for(i = 0;i<temp.size();i++){ ab[i] = temp[i] - 48; judge[i].resize(m+1); for(j=0;j<m+1;j++){ judge[i][j].resize(temp.size()); } } coutVector(digui(0,m,0)); //清除数组空间 for(i = 0;i<temp.size();i++){ for(j=0;j<m+1;j++){ for(z=0;z<temp.size();z++){ judge[i][j][z].clear(); } judge[i][j].clear(); } judge[i].clear(); } judge.clear(); ab.clear(); } return 0; } //a表示当前到达数组ab的那个位置,b表示还剩下几个"+" //c表示上一个"+"右边的位置 vector<int> digui(int a,int b,int c){ if(b == 0){//如果"+"已经给完,直接将后面的返回 vector<int> d(ab.begin()+a,ab.end()); return judge[a][b][c] = d; } if(b > ab.size()-1-a || a >= ab.size()){//"+"大于等于剩余位数返回错误 return notPass; } if(judge[a][b][c].size() != 0){ //备忘录的用法 return judge[a][b][c]; } vector<int> x = digui(a+1,b,c); //x代表没有给当前位数后面"+"的值 vector<int> y(ab.begin()+c,ab.begin()+a+1);//y代表在当前位数后面给了 "+" y = AddBigNum(y,digui(a+1,b-1,a+1));//则y等于前一段加上后面的和 if(compare(x,y)){//比较大小,谁小返回谁 return judge[a][b][c] = y; }else{ return judge[a][b][c] = x; } } //比较大小,true表示a>=b,false则是a<b bool compare(vector<int> a,vector<int> b){ if(a.size() > b.size()){ return true; }else if(a.size() < b.size()){ return false; } for(int i = 0; i<a.size() ;i++){ if(a[i] > b[i]){ return true; }else if(a[i] < b[i]){ return false; } } return true; } //返回a+b的数组 vector<int> AddBigNum(vector<int> a,vector<int> b){ reverse(a.begin(),a.end()); reverse(b.begin(),b.end()); int i=0,j=0; vector<int> c; int temp = 0; while(i<a.size() && i<b.size()){ temp += a[i]+b[i]; c.push_back(temp%10); temp /= 10; i++; } while(i < a.size()){ temp += a[i]; c.push_back(temp%10); temp /= 10; i++; } while(i < b.size()){ temp += b[i]; c.push_back(temp%10); temp /= 10; i++; } if(temp != 0) c.push_back(temp); reverse(c.begin(),c.end()); return c; } //查BUG时为了方便写的打印数组 void coutVector(vector<int> a){ for(int i = 0;i<a.size();i++){ cout<<a[i]; } cout<<endl; }