有时候,编程仅仅是为了代替人力劳动。
通过这道题,你可以掌握
- 编写愚蠢的算法虐待自己的电脑
题目
给你 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
给了十分钟让人解答。
首先,理解题意花掉了大概三分钟。
剩下七分钟,胡思乱想,设十个变量,列十个方程求解?
似乎发现到规律,下面十个数相加等于10!
and then ...???
十分钟过去了,不死心,继续想。。。
其实有时候,算法并没有那么高深莫测,算法仅仅是人脑的反映,将算法变成计算机能识别的语言,让计算机帮忙运算,这才是编程的初衷。
思路
不断地循环遍历下排数字,使之满足是上排那十个数在下排出现的次数,直到有一次遍历,
是所有下排的数都满足这个要求,这时就找到题目所要求的十个数
呵呵,很愚蠢很繁琐的算法,但事实就是这样。
源代码
#include <stdio.h>
#include<stdlib.h>
#include <iostream>
using namespace std;
/**
给你 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
思路
不断地循环遍历下排数字,使之满足是上排那十个数在下排出现的次数,直到有一次遍历,
是所有下排的数都满足这个要求,这时就找到题目所要求的十个数
*/
#define len 10
class NumberTB
{
public:
int top[len];
int bottom[len];
bool success;
NumberTB();
int* getBottom();
void setNextBottom();
int getFrequecy(int num);
};
void printArray(int arr[len]){
for(int i =0;i<len;i++){
cout<<arr[i]<<endl;
}
}
//初始化上排数
NumberTB::NumberTB()
{
success = false;
//format top
for(int i=0;i<len;i++)
{
top[i] = i;
}
}
//获得下排数
int* NumberTB::getBottom()
{
int count = 0;//计数器
while(!success)
{
count++;
setNextBottom();
//这里需要一个判断,判断是否这个数组不可能做到
//下排每个数都是先前上排那十个数在下排出现的次数
/**
{
}
*/
}
return bottom;
}
//设置下排数,使其等于上排数在下排的次数
void NumberTB::setNextBottom()
{
bool reB = true;
for(int i=0;i<len;i++)
{
int frequecy = getFrequecy(top[i]);//获得上排数在下排的次数
if(bottom[i] != frequecy)
//遍历过程中,只要有一次下排数bottom[i]不等于上排数在下排的次数frequecy
//则reB = false;getBottom会再循环一次,执行setNextBottom
//直到所有数都满足,才能跳出循环
{
bottom[i] = frequecy;
reB = false;
}
}
success = reB;
}
/**统计上排的数在下排出现的次数
num 上排的数
*/
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
}
void main()
{
NumberTB nTB;
int* result= nTB.getBottom();
for(int i=0;i<len;i++)
{
cout<<*result++<<endl;
}
//printArray(nTB.bottom);
system("pause");
}
有时候,算法就是这么“愚蠢”,不要想太多。
ps:此题为腾讯面试题。