原文:https://www.luogu.org/problemnew/solution/P1018?page=7數組
題目:P1018【乘積最大】函數
前言:spa
總體思路:code
上代碼:blog
#include<algorithm> //使用next_permutation須要調用的頭文件 #include<cstdio> //c語言讀入輸出 #include<cstring> //處理高精度字符串時須要用到 using namespace std; struct BigN{ //高精度(即大整數)運算 int num[1001]={0},len; BigN(char s[]) //構造函數,用於給新定義的大整數賦值 { len=strlen(s); for(int i=len-1;i>=0;i--) num[i]=s[len-i-1]-'0'; } void clean() //用於清零 { memset(num,0,sizeof(num)); } void f(int n) //將一個普通整數壓到大整數的開頭,這個在後面分割每一位時會用到 { for(int i=len;i>0;i--) num[i]=num[i-1]; len++; num[0]=n; } void cheng(BigN n)//高精度乘法,這裏就不過多解釋了,有疑問能夠前往 P1303 瞭解更多 { BigN c("0"); int s=0,g=0; for(int i=0;i<=len;i++) for(int j=0;j<=n.len;j++) { int w=i+j; s=num[i]*n.num[j]; c.num[w]+=s%10; c.num[w+1]+=s/10+c.num[w]/10; c.num[w]%=10; } c.len=len+n.len; while(c.num[c.len]==0&&c.len>=0)c.len--; fz(c); } void fz(BigN n) //將一個大整數賦值給例外一個大整數,至關於'=' { len=n.len; for(int i=0;i<=n.len;i++) num[i]=n.num[i]; } bool bj(BigN n) //判斷兩個大整數的大小,用於找出最大結果 { if(len>n.len) return 1; else if(len<n.len) return 0; else { for(int i=len;i>=0;i--) if(num[i]<n.num[i]) return 0; else if(num[i]>n.num[i]) return 1; return -1; } } void out() //輸出 { for(int i=len;i>=0;i--) printf("%d",num[i]); } }; int n,k,sum[55],b[55],i,j; //常規定義,很少作解釋 BigN mmax("0"); int main() { char s[101]; //s用於讀入一個大整數 scanf("%d%d%s",&n,&k,&s); for(i=0;i<strlen(s);i++) //在sum中備份一份原數 sum[i]=s[i]-'0'; for(i=n-2;i>=(n-k)-1;i--) //將b數組中的後k個數賦1,由於使用next_permutation須要讓數組升序,不然可能沒法找出全部排列方式 b[i]=1; do{ BigN temp("0"),all("1");//temp用於存放分割後的每一節,all用於計算每種排列方式的結果 i=0; while(i<n)//分割 { if(i!=0) if(b[i-1]==1)//若是b[i-1]爲1,那麼就要在這一位加上一個乘號,即將原數分割 all.cheng(temp),temp.clean();//總數乘上分割後的每一位,並將temp清空,用於儲存下一節. temp.f(sum[i]),i++; //將原數的下一位壓到temp的最前面 } all.cheng(temp);//因爲temp尚未乘all就退出循環,因此要再乘一次 if(mmax.bj(all)==0)//若是這種排列順序的結果大於以前最大的結果,刷新最大結果 mmax.fz(all); }while(next_permutation(b,b+n-1));//調用next_permutation mmax.out();//輸出 return 0; }