Problem Statement for TheLuckySum (自己写的二叉树实现的4,7幸运数字算法。记录下来)
来源:互联网 发布:超次元矩阵要关服了吗 编辑:程序博客网 时间:2024/05/22 06:40
题目:
Problem Statement for TheLuckySum
Problem Statement
John thinks 4 and 7 are lucky digits, and all other digits are not lucky. A lucky number is a number that contains only lucky digits in decimal notation.
Some numbers can be represented as a sum of only lucky numbers. Given an int n, return a int[] whose elements sum to exactly n. Each element of the int[] must be a lucky number. If there are multiple solutions, only consider those that contain the minimum possible number of elements, and return the one among those that comes earliest lexicographically. A int[] a1 comes before a int[] a2 lexicographically if a1 contains a smaller number at the first position where they differ. If n cannot be represented as a sum of lucky numbers, return an empty int[] instead.
Definition
Class: TheLuckySum
Method: sum
Parameters: int
Returns: int[]
Method signature: int[] sum(int n)
(be sure your method is public)
Constraints
- n will be between 1 and 1,000,000,000, inclusive.
Examples
0)
11
Returns: {4, 7 }
It is simple: 11 = 4 + 7.
1)
12
Returns: {4, 4, 4 }
Now we need three summands to get 12.
2)
13
Returns: { }
And now we can not get 13 at all.
3)
100
Returns: {4, 4, 4, 44, 44 }
测试数据用例:
11 {4, 7}
12 {4, 4, 4}
13 {}
100 {4, 4, 4, 44, 44}
1000000000 {4, 4, 44444444, 477777774, 477777774}
48 {4, 44}
1 {}
57 {4, 4, 7, 7, 7, 7, 7, 7, 7}
25 {4, 7, 7, 7}
69 {4, 4, 7, 7, 47}
3603 {444, 444, 444, 747, 747, 777}
3456 {444, 744, 744, 747, 777}
3812 {47, 747, 747, 747, 747, 777}
3580 {4, 474, 774, 774, 777, 777}
3824 {44, 744, 744, 744, 774, 774}
957147 {4, 4, 444, 4444, 474474, 477777}
951000 {444, 444, 444, 444, 474447, 474777}
913356 {74, 4474, 44477, 44777, 44777, 774777}
971124 {4, 44, 4444, 44444, 444444, 477744}
998368 {44, 44, 444, 4444, 44444, 474474, 474474}
1 {}
2 {}
3 {}
4 {4}
5 {}
6 {}
7 {7}
8 {4, 4}
9 {}
10 {}
17 {}
18 {4, 7, 7}
19 {4, 4, 4, 7}
20 {4, 4, 4, 4, 4}
21 {7, 7, 7}
744399 {4, 4, 44, 474, 44774, 74774, 74774, 74774, 474777}
源代码:
/*
*:author:ChenGuoSong
*:date:2010-07-14
*/
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
int isLuckNum(int i)
{
if(0==i)
return 0;
while(i)
{
if(i%10==4||i%10==7)
i = i/10;
else
return 0;
}
return 1;
}
//幸运数字二叉树节点
typedef struct BiTree
{
int num7; //7的个数
int num4; //4的个数
int radix; //基数
int originalNum;//被分解的整数
int minCount; //可分解的个数最小限制
int minCP; //和父亲节点minCount的差值
BiTree *leftSon;
BiTree *parent;
BiTree *rightSon;
}BTree;
//临时变量,用于输出打印结果
stack<BTree*,vector<BTree*> > leafToRootStack ,leafToRootStackTmp1 ,leafToRootStackTmp2;
//分解整数,得到分解的4,7个数
int spilteNumber(int originalNum, int minCount, int &num7, int &num4, int &leftNum,int &radix,int isRightSon);
//打印结果
void print(stack<BTree*,vector<BTree*> > sp);
//取得整数的长度
int getIntLen(int i)
{
int len = 1;
while(i/=10)
len ++;
return len;
}
//取得当前长度的最小幸运数字
int getMinLuck(unsigned int len)
{
int i = 4;
while(--len)
i = i*10+4;
return i;
}
int powInt(unsigned int len)
{
int i = 1;
while(--len)
i *= 10;
return i;
}
//判断数是否可分解成幸运数字
int isSplited(int num)
{
if (0>num)
return 0;
else if(11==num||15==num||17<num||0==num%4||0==num%7)
return 1;
else
return 0;
}
//得到可分解的最高位数
int getSpliteNum(int originalNum ,int len,int minCount,int radix)
{
int dif = originalNum-getMinLuck(len);
if(0>=originalNum||(1==len&&4!=originalNum&&7!=originalNum&&8!=originalNum))
return 0;
if(1==len)
return originalNum;
else if(10!=len
&&((0<minCount&&originalNum<radix)
||(0==minCount&&(isSplited(dif)||dif==3||10==dif||17==dif))))
return originalNum/powInt(len);
else
return originalNum/powInt(len-1);
}
//建立节点
int createNode(BTree *(&bitree),const BTree * const btParent)
{
if(NULL==bitree)
{
int originalNum = btParent->originalNum,minCount = btParent->minCount,num7 = 0,num4 =0,leftNum=0,radix = btParent->radix,isRightSon=0;
if(NULL!=btParent->leftSon)
isRightSon=1;
if(spilteNumber(originalNum,minCount,num7,num4,leftNum,radix,isRightSon))
{
bitree = new BTree;
bitree->originalNum = leftNum;
bitree->minCount = num7+num4;
bitree->minCP = num7+num4-minCount;
bitree->num7 = num7;
bitree->num4 = num4;
bitree->radix = radix;
bitree->parent = (BTree*)btParent;
bitree->leftSon = NULL;
bitree->rightSon = NULL;
}else
return 0;
}else
return 1;
}
//先序建立二叉树
int preOrderCreateBTree(BTree *&bt,const BTree * const btParent)
{
if(createNode(bt,btParent))
if(preOrderCreateBTree(bt->leftSon,bt))
if(preOrderCreateBTree(bt->rightSon,bt))
return 1;
return 1;
}
//遍历二叉幸运树,得到最幸运的一个分支
int findLeafToROOt(BTree * bt)
{
int size = 0;
if(NULL!=bt)
{
leafToRootStack.push(bt);
if(NULL==bt->leftSon&&NULL==bt->rightSon)
{
if(bt->originalNum==0)
{
stack<BTree*,vector<BTree*> > leafToRootStackTmp = leafToRootStack;
if(leafToRootStackTmp1.empty())
{
leafToRootStackTmp1 = leafToRootStack;
leafToRootStackTmp2 = leafToRootStack;
}
else
{
stack<BTree*,vector<BTree*> > leafToRootStackTmpbak = leafToRootStackTmp1 ;
leafToRootStackTmp2 = leafToRootStack;
while(!leafToRootStackTmp1.empty()&&!leafToRootStackTmp2.empty())
{
if(leafToRootStackTmp1.top()->minCount<leafToRootStackTmp2.top()->minCount)
{
leafToRootStackTmp1 = leafToRootStackTmpbak ;
break;
}else if(leafToRootStackTmp1.top()->minCount==leafToRootStackTmp2.top()->minCount)
{
if(leafToRootStackTmp1.top()->minCP==leafToRootStackTmp2.top()->minCP)
{
leafToRootStackTmp1.pop();
leafToRootStackTmp2.pop();
continue;
}else if(leafToRootStackTmp1.top()->minCP>leafToRootStackTmp2.top()->minCP)
{
leafToRootStackTmp1 = leafToRootStackTmpbak ;
break;
}else
{
leafToRootStackTmp1 = leafToRootStack;
break;
}
}else
{
leafToRootStackTmp1 = leafToRootStack;
break;
}
}
}
}
}
if(findLeafToROOt(bt->leftSon))
{
if(NULL!=bt->leftSon)
leafToRootStack.pop();
if(findLeafToROOt(bt->rightSon))
{
if(NULL!=bt->rightSon)
leafToRootStack.pop();
return 1;
}
}
}
else
return 1;
}
int delBTree(BTree *&bt)
{
if(NULL!=bt)
if(delBTree(bt->leftSon))
if(delBTree(bt->rightSon))
{
delete [] bt;
bt = NULL;
return 1;
}
return 1;
}
int main(int argc,char *argv[])
{
while(1)
{
BTree *rootNode = new BTree;
cout << "input Number: " ;
cin >> rootNode->originalNum;
//cout << i << " ";
if(0>rootNode->originalNum)
break;
if(isLuckNum(rootNode->originalNum))
{
cout << "the result:" << rootNode->originalNum <<" "<< endl;
//cout << rootNode->originalNum <<" "<< endl;
delete [] rootNode;
rootNode = NULL;
continue;
}
rootNode->minCount = 0;
rootNode->num7 = 0;
rootNode->num4 = 0;
rootNode->radix = powInt(getIntLen(rootNode->originalNum));
rootNode->minCP = 0;
rootNode->parent = NULL;
rootNode->leftSon = NULL;
rootNode->rightSon = NULL;
preOrderCreateBTree(rootNode,rootNode->parent);
findLeafToROOt(rootNode);
cout << "the result:";
print(leafToRootStackTmp1);
delBTree(rootNode);
while(!leafToRootStackTmp1.empty())
leafToRootStackTmp1.pop();
while(!leafToRootStackTmp2.empty())
leafToRootStackTmp2.pop();
while(!leafToRootStack.empty())
leafToRootStack.pop();
}
cout << "good bye!" << endl;
return 1;
}
//打印结果
void print(stack<BTree*,vector<BTree*> > sp)
{
vector<int> v,vTmp;
int size = sp.size();
for(int i=0;i<size-1;i++)
{
if(0==i)
{
for(int k=0;k<sp.top()->num4;k++)
{
v.push_back(4);
}
for(int k=0;k<sp.top()->num7;k++)
{
v.push_back(7);
}
}else
{
for(int k=0;k<sp.top()->num7;k++)
{
if(!v.empty())
{
vTmp.push_back(v.back()+7*sp.top()->radix);
v.pop_back();
}
}
for(int k=0;k<sp.top()->num4;k++)
{
if(!v.empty())
{
vTmp.push_back(v.back()+4*sp.top()->radix);
v.pop_back();
}
}
while(!vTmp.empty())
{
v.push_back(vTmp.back());
vTmp.pop_back();
}
}
sp.pop();
}
if(v.empty())
{
cout << "此数无法分解" << endl;
return ;
}
vector<int>::iterator it;
for ( it=v.begin() ; it < v.end(); it++ )
cout << *it << " ";
cout << endl;
}
//数的分解
int spilteNumber(int originalNum, int minCount, int &num7, int &num4, int &leftNum,int &radix,int isRightSon)
{
int len = getIntLen(originalNum);
int spilteNum = getSpliteNum(originalNum,len,minCount,radix);
if(0==spilteNum)
return 0;
if(spilteNum>=10)
radix = powInt(--len);
else
radix = powInt(len);
int RightSonFlag = 1;
while(spilteNum>=4)
{
for(int k = spilteNum/7; k>=0; k--)
for(int i = (spilteNum-k*7)/4;i*4+7*k<=spilteNum; i++)
{
leftNum = originalNum-7*k*radix-4*i*radix;
int dif = leftNum-(i+k)*getMinLuck(len-1==0?1:len-1);
if(i*4+7*k==spilteNum&&i+k>=minCount
&&((1<len
&&(isSplited(dif)||3==dif||((6==dif||13==dif)&&2<=k+i)||(9==dif&&3<=k+i)||10==dif||17==dif)
&&isSplited(leftNum))
||(1==len&&spilteNum==originalNum)))
{
if(isRightSon)
{
isRightSon = 0;
RightSonFlag = spilteNum;
goto breakPoint;
}else
{
num7 = k, num4 = i;
return 1;
}
}
}
breakPoint:
spilteNum--;
if(1<RightSonFlag-spilteNum)
break;
}
return 0; //分解失败
}
- Problem Statement for TheLuckySum (自己写的二叉树实现的4,7幸运数字算法。记录下来)
- Problem Statement for TheLuckySum
- 好吉利的数字,记录下来吧
- 记录一下自己东粘西贴,自己敲下来的排序算法代码。
- Begin 写博客啦,将自己每天的收获记录下来
- 幸运的数字8888
- QAQ的幸运数字
- QAQ的幸运数字
- 4和7为幸运数字,判断[a,b]之间所有由幸运数字组成的数字的个数
- 二叉查找树(自己写的版本)
- 自己写的一个小程序查询菜谱cookbook,主要是记录下来以备日后查询
- 自己实现的二叉树
- 将一些对自己工作指导意义的事情记录下来
- 写在前面 把自己的学习之路记录下来
- 将自己积累的一些笔记记录下来
- 多写Blog,把遇到的问题记录下来
- 写matlab程序中用记录下来的小碎片
- 进程调度算法实现(自己写的)
- C# 获取 父类和子类的集合
- JSON知识
- Remove all the EventHandlers of the object by reflection
- ZK开发的CRM系统
- Java多线程开发七——线程安全的数据结构
- Problem Statement for TheLuckySum (自己写的二叉树实现的4,7幸运数字算法。记录下来)
- 过程文档化 - 思想、行为、习惯
- 在Java中读取并保存EXCEL文件中图片
- 《ASCE1885的网络编程》---地址解析协议
- 【hnoi2010】平面图判定
- 联发科成也Turnkey,衰也Turnkey
- 用rowid 删除的方法
- What ASP.NET Programmers Should Know About Application Domains
- C++的起点