根据上排给出的十个数,在其下排填出对应的十个数(腾讯面试题)
题目:
腾讯面试题:
给你10 分钟时间,根据上排给出十个数,在其下排填出对应的十个数
要求下排每个数都是先前上排那十个数在下排出现的次数。
上排的十个数如下:
【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 次....
以此类推..
思路:这道题看了几分钟没看懂,晕。终于看懂了
首先找下规律吧:
因为要求下面填入的是上面行的数对应在下面行出现的次数。那么,可以得出下面行的总和也就为上面行在下面行出现的总次数,并且很明显数就只有10个,那么总次数就为10。可以得出第二行数的综合为10.也可以看出,第一行的数对应第二行的数不为0,那么必定在第二行出现过,并且是出现过第二行次。举个例:比如下面的第一行的数字1在第二行的数为2,说明第二行就有两个1出现。所以,可以得出的结论是第一行的数乘以第二行对应的数等于总次数10.举个例:下面两行中2×1+1×2+6×1=10.
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|
6 | 2 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
|
因此,可以得出两个线性方程组:
设10个变量:x1, x2, x3, x4, x5, x6, x7, x8,x9, x10
则,直接解一个线性方程组即可,可以直接求出通解。那么就是一个简单的线性代数求解问题了。
上面的方法可行,但是会消耗大量时间。
下面给出另一种思路:
上面的10个数为top[10],下面设为bottom[10],top[i]=i,bottom[10]={0};
一开始将下面的10个数全部设置为0,不停迭代计算到最后不发生变化就可以了。
如:0 1 2 3 4 5 6 7 8 9
0 0 0 0 0 0 0 0 0 0 0
接下来迭代:
代码:
- #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;
- }