能量晶石
Jack 正在组装自己的飞行器,他希望从手中的一些很奇怪的能量晶石中,选择一块,作为飞行器引擎的能量来源。
每个晶石,都用一连串的数字进行标注。 可以整块使用,也可以通过对晶石的切割,得到不同强度的能量输出。
切割后,各个晶石片段能量强度之和计算方式为:各个晶石片段上的整数之和。(不可把单个数字切割成 2 半)。
由于飞行器引擎所能承受的能量强度存在上限,切割完的晶石片段,能量强度之和不能超过上限,否则将导致引擎过载。同时,为节省晶石的浪费, Jack 希望一块晶石切下来的所有片段,都必需加入到飞行器引擎中,不能丢弃。
例:晶石“ 352143”,可分割为 35,214,3。它们的能量强度之和为 252。也可分割为
352,143,能量强度和为 495
Jack 希望知道,在不导致引擎过载的同时,手中的这些能量晶石, 各自能够达到的最
接近引擎上限的能量强度是多少。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<math.h> 4 #include<string.h> 5 #include<algorithm> 6 #include<iostream> 7 using namespace std; 8 int func(char sc[],char b[],int flag) 9 { 10 int last=-1,t,r,m,sum=0,len=strlen(sc); 11 char part[20]; 12 for(t=0;t<len;t++) 13 { 14 if(b[t]=='1') 15 { 16 r=0; 17 for(m=last+1;m<=t;m++) 18 { 19 part[r++]=sc[m]; 20 } 21 part[r]='\0'; 22 sum+=atoi(part); 23 if(flag==1) 24 printf("%d ",atoi(part)); 25 last=t; 26 } 27 } 28 if(last!=len-1) 29 { 30 r=0; 31 for(m=last+1;m<len;m++) 32 { 33 part[r++]=sc[m]; 34 } 35 part[r]='\0'; 36 sum+=atoi(part); 37 if(flag==1) 38 printf("%d\n",atoi(part)); 39 } 40 return sum; 41 } 42 int main() 43 { 44 int n,i,j,limit,Q,t,len,sum,a[131072],max=-1,m; 45 char b[20],num[20],s[20],ans[20]; 46 scanf("%d",&Q); 47 for(j=0;j<Q;j++) 48 { 49 scanf("%s %d",num,&limit); 50 m=0; 51 n=strlen(num)-1; 52 max=-1; 53 for(i=0;i<int(pow(2,n));i++)//生成所有切割方案 54 { 55 itoa(i,b,2); 56 if(strlen(b)<n) 57 { 58 len=strlen(b); 59 for(t=0;t<n-len;t++) 60 s[t]='0'; 61 s[t]='\0'; 62 strcat(s,b); 63 strcpy(b,s); 64 } 65 sum=func(num,b,0); 66 if(sum<=limit&&sum>=max) 67 { 68 a[m++]=sum; 69 max=sum; 70 strcpy(ans,b); 71 } 72 } 73 if(m>0) sort(a,a+m);//若有多种方案,能量和均能达到最接近引擎上限 74 if(m==0) 75 { 76 printf("Error\n"); 77 } 78 else if(a[m-1]==a[m-2]&&m>1) 79 { 80 printf("Oooops\n"); 81 } 82 else 83 { 84 sum=func(num,ans,1); 85 } 86 } 87 return 0; 88 }