微软100题(6) 根据上排给出十个数,在其下排填出对应的十个数

题目:

根据上排给出十个数,在其下排填出对应的十个数  

要求下排每个数都是先前上排那十个数在下排出现的次数。  
上排的十个数如下:  
【0,1,2,3,4,5,6,7,8,9】 

举一个例子,  
数值: 0,1,2,3,4,5,6,7,8,9  
分配: 6,2,1,0,0,0,1,0,0,0  
0在下排出现了6次,1在下排出现了2次,  
2在下排出现了1次,3在下排出现了0次....  

数学上的理解:

上排数字0 1 2 。。。n-1,则下排数字之和为n,因为下排每个数字都是对应的上排在下排出现的次数,下面一共n个坑,第一个占x个,还剩下n-x个坑,还需要n-x个数需要分配,所以下排数字和为n,则上排中较大的数字基本都是零,只有一个不为零,对应下排中总共0的个数。1+2+3=6了,倘若3下面不为零,则下面至少有3个数字下面不是零,显然不满足。所以只能1 2下面不为零。0 1 2和后面大数有一个不为零,共计4个不为零,则0下面6 那么大数就是6 6下面是1 1和2下面的1*x+2*y=10-6=4 x=2 y=1 退出 6 2 1 0 0 0 1 0 0 0

n = 19

0 1 2 3 4 5 6 7 8 9.。。19

同样方法推出:

16 2 1 。。。。 1 0 0 0


网上的一个回溯试探法:

不断去测试,直到所有的对应位数字符合要求,则success。


#include <iostream.h>
#define len 10

class NumberTB  
{  
private:
    int top[len];  
    int bottom[len];
    bool success;
public:
    NumberTB();
    int* getBottom();
    void setNextBottom();
    int getFrequecy(int num);
};
NumberTB::NumberTB()  
{    
    success = false;  
    //format top   
    for(int i=0;i<len;i++)  
    {  
        top[i] = i;          
    }          
}
int* NumberTB::getBottom()
{  
    int i = 0;      
    while(!success)  
    {  
        i++;  
        setNextBottom();  
    }          
    return bottom;  
} 

//set next bottom   
void NumberTB::setNextBottom()  
{  
    bool reB = true;  
   
    for(int i=0;i<len;i++)  
    {  
        int frequecy = getFrequecy(i);  
       
        if(bottom[i] != frequecy)  
        {  
            bottom[i] = frequecy;  
            reB = false;  
        }  
    }  
    success = reB;  
} 

//get frequency in bottom   
int NumberTB::getFrequecy(int num)   //此处的num即指上排的数 i
{  
    int count = 0;  
   
    for(int i=0;i<len;i++)  
    {  
        if(bottom[i] == num)  
            count++;  
    }  
    return count;    //cout即对应 frequecy
}
int main()
{   
    NumberTB nTB;
    int* result= nTB.getBottom(); 

    for(int i=0;i<len;i++) 
    {  
        cout<<*result++<<endl;  
    }  
    return 0;
}      



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值