i 、每次从通里面拿出来两个球;
ii、如果取出的是两个同色的求,就再放入一个黑球;
ii、如果取出的是两个异色的求,就再放入一个白球。
问:最后桶里面只剩下一个黑球的概率是多少?
这个是百度的面试题目,如果写程序会发现,全是黑色的。
这个问题还是要有计算机的2进制思维,把白色的当做1,黑色当做0,1+1=0,就是取两个白色的,放进去一个黑色的。
1+1=0;
1+0=1;
0+0=0;
最终的结果是0,黑色的,一堆0,1相加。
2、(华为)通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串压缩程序,将字符串中连续出席的重复字母进行压缩,并输出压缩后的字符串。
压缩规则:
1、仅压缩连续重复出现的字符。比如字符串"abcbc"由于无连续重复字符,压缩后的字符串还是"abcbc"。
2、压缩字段的格式为"字符重复的次数+字符"。例如:字符串"xxxyyyyyyz"压缩后就成为"3x6yz"。
要求实现函数:
void stringZip(const char *pInputStr, long lInputLen, char *pOutputStr);
输入pInputStr: 输入字符串lInputLen: 输入字符串长度
输出 pOutputStr: 输出字符串,空间已经开辟好,与输入字符串等长;
注意:只需要完成该函数功能算法,中间不需要有任何IO的输入输出
示例
输入:“cccddecc” 输出:“3c2de2c”
输入:“adef” 输出:“adef”
输入:“pppppppp” 输出:“8p”
void stringZip(const char *pInputStr, long lInputLen, char *pOutputStr){
int i=0;
char C=*pInputStr;
int number=1;
for(i=1;i<lInputLen;i++){
if(C==*(pInputStr+i)){
number++;
}
else{
if(number!=1){
char temp[10];
itoa(number,temp,10);
strcat(pOutputStr,temp);
temp[0]=C;
temp[1]='\0';
strcat(pOutputStr,temp);
}
else{
char temp[2];
temp[0]=C;
temp[1]='\0';
strcat(pOutputStr,temp);
}
C=*(pInputStr+i);
number=1;
}
}
if(number!=1){
char temp[10];
itoa(number,temp,10);
strcat(pOutputStr,temp);
temp[0]=C;
temp[1]='\0';
strcat(pOutputStr,temp);
}
else{
char temp[2];
temp[0]=C;
temp[1]='\0';
strcat(pOutputStr,temp);
}
}
为了用strcat而用strcat,写的不好。没有安全检查,assert( (pInputStr != NULL) && (pOutputStr!= NULL) );
3、(网新恒天)2014校园招聘笔试编程题
已知memcpy的函数为: void* memcpy(void *dest , const void* src , size_t count)其中dest是目的指针,src是源指针。不调用c++/c的memcpy库函数,请编写memcpy。
这个是参考答案,别人的。
void* memcpy(void *dst, const void *src, size_t count)
{
//安全检查
assert( (dst != NULL) && (src != NULL) );
unsigned char *pdst = (unsigned char *)dst;
const unsigned char *psrc = (const unsigned char *)src;
//防止内存重复
assert(!(psrc<=pdst && pdst<psrc+count));
assert(!(pdst<=psrc && psrc<pdst+count));
while(count--)
{
*pdst = *psrc;
pdst++;
psrc++;
}
return dst;
}
4、迅雷2014校招笔试编程题(转):已知集合A和B的元素分别用不含头结点的单链表存储,函数difference()用于求解集合A与B的差集,并将结果保存在集合A的单链表中。例如,若集合A={5,10,20,15,25,30},集合B={5,15,35,25},完成计算后A={10,20,30}。
链表结点的结构类型定义如下:
struct node
{
int elem;
node* next;
};
填空:
void difference(node** LA , node* LB)
{
node *pa , *pb , *pre , *q;
pre = NULL;
//1
while(pa)
{
pb = LB;
while( ) //2
pb = pb->next;
if( ) //3
{
if(!pre)
*LA = ; //4
else
= pa->next; //5
q = pa;
pa = pa->next;
free(q);
}
else
{
; //6
pa = pa->next;
}
}
}
1、2、3、4、5、6六行代码依次为
pa = *LA;
pb && pa->elem != pb->elem
pb
pa->next
pre->next
pre = pa;
代码中的指针pa用于指向集合A的元素;pb指向集合B的元素;临时指针q指向需要被删除的元素;pre用于实现删除时结点的链接,与pa保持所指结点的前后继关系。
5 人人校招
给定一个有序数组a,长度为len,和一个数X,判断a数组里是否存在两个数的和为X
函数:bool judge(int * a,int len,int X),存在返回true,否则返回false
这个问题其实挺简单的
bool judge(int *a,int len,int X){
if(a==NULL||len<=0)
return false;
int *first=a;
int *last=a+len-1;
while(first<last){
if(*first+*last>X)
last--;
else if(*first+*last==X)
return true;
else
first++;
}
return false;
}
6 (
阿里巴巴 北邮站)设计一个最优算法来查找一n个元素数组中的最大值和最小值。已知一种需要比较2n次的方法,请给一个更优的算法。请特别注意优化时间复杂度的常数。
有序和无序数组的算法问题,经常出现,排序、最大值最小值、中值等。
分析这个题目,其实我觉得有时候对于没有专门ACM训练过的,可能做算法都是靠灵感,如果想到了,则会通过,否则可能就会想到一些笨方法。这个算法主要是能想到两两比较就好。
2n的情况是遍历两次数组,分别求最大和最小值。
如果要比2n小,分析将数组两两一组,分别比较出最大值和最小值(N/2次比较),然后求这一系列最小值的最小值,一系列最大值的最大值(分别为N/2),最终为3N/2次比较。
这里对最大值和最小值进行比较有交换操作,此时程序会做多于运算,可以考虑不交换。设置一个最大值Max和最小值Min,依次和每一组的两个数据做比较,把较大的值给Max,较小的值给Min,遍历一次就能找到数组的最大值和最小值。
分析方法自点击打开链接
7、(阿里巴巴 北邮站)已知三个升序整数数组a[l], b[m]和c[n]。请在三个数组中各找一个元素,是的组成的三元组距离最小。三元组的距离定义是:假设a[i]、b[j]和c[k]是一个三元组,那么距离为:Distance = max(|a[ I ] – b[ j ]|, |a[ I ] – c[ k ]|, |b[ j ] – c[ k ]|)
请设计一个求最小三元组距离的最优算法,并分析时间复杂度。
简单一个图可以看出数轴上3个数的两两之间的差的绝对值为多少,可自行证明之。
可以看出Distance其实就是AC之间距离的两倍,所以只需要AC之间的距离最小即可。
所以相应算法为设置最小值min,分别选取abc三个数组的最小值a[0],b[0],c[0]开始以下操作
选取当前a[i]、b[j]和c[k],计算当前三个数的最大值与最小值差值并更新min,选取当前三个数最小值,假设为a[i],然后将a数组向前滑一个数据,i=i+1,继续上步操作,即可得到结果。
算法的复杂度:三个数组的长度和,(l+m+n)
8、(阿里巴巴 北邮站)在黑板上写下50个数字:1至50.在接下来的49轮操作中,每次做如下动作:选取两个黑板上的数字a和b,擦去,在黑板上写|b - a|。请问最后一次动作之后剩下数字可能是什么?为什么?
这个可以先进行举例,50个数,26-1,27-1,...,50-25,然后奇数个25-25,最终得到25
如果是两两相减,则得到1,不再举例了。。。
可以思考一下,这个数一定是小于50的。。。至于为什么可以自己想。
这个数一定是一个奇数:类似于,01之间的异或操作。50个数中,25个偶数,25个奇数。互相相减后得到的是一个必为奇数。
这个数是50之内的任意奇数,没有证明,感谢http://blog.csdn.net/qingsong3333/article/details/11910771
只有凑的方法
假设取27这个数,来看如何凑出来。将1-50分成两份,1-27,28,29-50。1-27数组中,计算3-2,5-4,。。。,27-26,最终得到14个1,29-50则得到11个1,最终得到,28,25个1,25个1相减最终可以得到一个1,和28相减,则得到27.这个原理是凑,而凑是这个原理,以一个偶数进行分界,对数据进行相减,可以得到奇数个1,与相应偶数进行相减则得到该偶数的前一个的奇数。