题目大致为:
给定5个数字:1,3,9,27,81;只使用加减法,它们可以组合算出1到121之间的任意数,输出等式,大数总在小数前。如:输入 13,输出 9+3+1;输出41,输出81-27-9-3-1。
思路:
首先可以看出每个数表达的数字都有个范围,例如在整数区间[1,1]必须用到1,在整数区间[2,4]必须用到3,在整数区间[5,13]必须用到9,在整数区间[14,40]必须用到27,在整数区间[41,121]必须用到81。
可以推出,若一个数x>40,式子中必须有81;若13<x<=40,必须用到27;若4<x<=13,必须用到9;若1<x<=4,必须用到3。本题貌似可以采用减治方法,将数字一步步减小,直到为0。
例如:当x=60;x>40,则 81 必须在式子中;在判断得出60<81,它两之间的差为21,即81-21=60;此时问题就转化为利用1、3、9、27得出21;且13<21<40,则 27 必在式子中,它两之间差为6,即27-6=21;此时转化为从1、3、9,算出6;且5<6<13,则 9 必在式子中,它两之间差为3,即9-3=6;此时转化为从1、3,算出 3;可以直接得出最后得出的式子为81-(27-(9-3))),计算过程中注意消括号,符号变换即可。
#include <iostream>
#include <string>
using namespace std;
string chaiFen(int k)
{
int exist[5]={81,27,9,3,1};
int total[5]={40,13,4,1,0};
string str[5]={"81","27","9","3","1"};
string result="";
bool fuHao;
int temp[5];
int gap,index=0;
int i,start=4;
gap=k;
fuHao=true; //true表示正号,false表示负号
while(true)
{
for(i=index;i<5;i++)
{
if(gap>total[i])
{
start=i;
break;
}
}
index=i+1;
if(gap==exist[start])
{
result+=str[start];
break;
}
else
{
if(gap>exist[start]&&fuHao==true)
{
result+=str[start]+"+";
gap=gap-exist[start];
continue;
}
if(gap<exist[start]&&fuHao==true)
{
result+=str[start]+"-";
gap=exist[start]-gap;
fuHao=false;
continue;
}
if(gap>exist[start]&&fuHao==false)
{
result+=str[start]+"-";
gap=gap-exist[start];
continue;
}
if(gap<exist[start]&&fuHao==false)
{
result+=str[start]+"+";
gap=exist[start]-gap;
fuHao=true;
continue;
}
}
}
return result;
}
int main()
{
int k,i;
string a;
cin>>k;
a=chaiFen(k);
cout<<a<<endl;
return 0;
}