C++笔试题集


获取C++primer

二、删除一个单项链表的最中间的元素,要求时间尽可能短(不能使用两次循环)
struct link
{
int data;
struct link *next;
};
void delMiddle(link *head)
{
if(head == NULL)
return;
else if(head->next == NULL)
{
delete head;
return;
}
else
{
link *low = head;
link *fast = head->next;
while(fast != NULL && fast->next != NULL)
{
fast = fast->next->next;
if(fast == NULL)
break;
low = low->next;
}
link *temp = low->next;
low->next = low->next->next;
delete temp;

}
}
int main()
{
struct link *head,*l;
struct link *s;
head = (link*)malloc(sizeof(link));
head->data=0;
head->next = NULL;
l = head;
for(int i=1; i<9; i++)
{
s = (link*)malloc(sizeof(link));
s->data = i;
s->next = NULL;
l->next= s;
l = l->next;
}
print(head);
delMiddle(head);
print(head);
return 0;
}

三、输入n,求一个n*n矩阵,规定矩阵沿45度线递增(威盛)
/**
* 得到如下样式的二维数组
* zigzag(jpeg编码里取象素数据的排列顺序)
*
* 0, 1, 5, 6,14,15,27,28,
* 2, 4, 7,13,16,26,29,42,
* 3, 8,12,17,25,30,41,43,
* 9,11,18,24,31,40,44,53,
* 10,19,23,32,39,45,52,54,
* 20,22,33,38,46,51,55,60,
* 21,34,37,47,50,56,59,61,
* 35,36,48,49,57,58,62,63
*/
void zigzag(int n)
{
int **a =(int**) malloc(n*sizeof(int *)); //分配空间

if(NULL == a)
return ;
int i;
for(i = 0; i < n; i++) {
if((a[i] =(int*) malloc(n * sizeof(int))) == NULL) {
while(--i>=0)
free(a[i]);
free(a);
return;
}
}

bool flag = false; //这个标志位用来判断是从45度角生成还是225度角生成
int count = 0;
for(i=0; i<n; i++) //生成的上半部分的数据
{

if(flag)
{
for(int r = 0; r<=i; r++)
{
a[r][i-r] = count;
count++;
}
flag = false;
}
else
{
for(int r = i; r>=0; r--)
{
a[r][i-r] = count;
count++;
}
flag = true;
}
}
for(i=n-1; i>=0; i--) //生成的是下半部分的数据
{
// cout<<i<<endl;
if(flag)
{
for(int r = 0; r<=i-1; r++)
{
int r1 = n-i+r; //代表当前行
int c1 = 2*n-i-1-r1; //代表当前列
a[r1][c1] = count;
count++;
}
flag = false;
}
else
{
for(int r = i-1; r>=0; r--)
{
cout<<"ddd"<<endl;
int r1 = n-i+r;
int c1 = 2*n-i-1-r1;
// cout<<r1<<","<<c1<<endl;
a[r1][c1] = count;
count++;
}
flag = true;
}
}
for(int r = 0; r<n; r++)
{
for(int c=0; c<n; c++)
cout<<a[r][c]<<",";
cout<<endl;
}
}
int main()
{
int n;
cin>>n;
zigzag(n);
return 0;
}
网上还有一个人写了一个比较巧的算法:
/**
* 得到如下样式的二维数组
* zigzag(jpeg编码里取象素数据的排列顺序)
*
* 0, 1, 5, 6,14,15,27,28,
* 2, 4, 7,13,16,26,29,42,
* 3, 8,12,17,25,30,41,43,
* 9,11,18,24,31,40,44,53,
* 10,19,23,32,39,45,52,54,
* 20,22,33,38,46,51,55,60,
* 21,34,37,47,50,56,59,61,
* 35,36,48,49,57,58,62,63
*/

#include <stdio.h>
int main()
{
int N;
int s, i,j;
int squa;
scanf("%d", &N);
/* 分配空间 */
int **a =malloc(N *sizeof(int *));
if(a ==NULL)
return0;
for(i = 0; i < N; i++) {
if((a[i]= malloc(N *sizeof(int))) == NULL) {
while(--i>=0)
free(a[i]);
free(a);
return0;
}
}
/* 数组赋值 */
squa = N*N;
for(i = 0; i < N; i++)
for(j = 0; j < N; j++) {
s = i + j;
if(s <N)
a[i][j] = s*(s+1)/2 + (((i+j)%2 == 0)? i : j);
else {
s = (N-1-i) + (N-1-j);
a[i][j] = squa - s*(s+1)/2 - (N - (((i+j)%2 == 0)? i : j));
}
}
/* 打印输出 */
for(i = 0; i < N; i++) {
for(j = 0; j < N; j++)
printf("%-6d", a[i][j]);
printf("\n");
}
return0;
}

四、打印1到1000的整数,不能使用流程控制语句(for,while,goto等)也不能使用递归
1.
typedef struct _test{
staticint a;
_test(){
printf("%d\n",_test::a);
a++;
}
}Test;
intTest::a = 1;

int main()
{
Test tt[1000];
return0;
}
2.
#include <stdio.h>
#define B P,P,P,P,P,P,P,P,P,P
#define P L,L,L,L,L,L,L,L,L,L
#define L I,I,I,I,I,I,I,I,I,I,N
#define I printf( "%3d ",i++)
#define N printf( "\n ")
int main()
{
int i = 1;
B;
}

#define A(x) x;x;x;x;x;x;x;x;x;x;
int main()
{
int n = 1;
A(A(A(printf ("%d ", n++))));

return0;
}

五、struct S {
int i;
int * p;
};
void main()
{
S s;
int * p = &s.i;
p[0] = 4;
p[1] = 3;
s.p = p;
s.p[1] = 1;
s.p[0] = 2;
}
问程序会在哪一行死掉。(microsoft)
解: S s;
int * p =&s.i; //s.i的地址存储在p里
p[0] =4;//修改了s.i
p[1] =3;//修改了s.p
s.p = p; //s.p指向s.i
s.p[1] =1;//修改s.p本身
s.p[0] =2;//s.p指向的是0x00000001,尝试向这里写,出错
s.p[0] = 2; 时出错
因为s.p存的是s.i的地址,s.p[1]为s.p,当s.p[1]=1时,s.p此时存放的是1了,而不是地址s.i,故在s.p[0] = 2时出错.
此时相当于s.p=ox00000001;地址ox0000001 = 2;当然就出错了

如果语句s.p[0] =2先于s.p[1]=1则程序就不会出错.此时语句相当于s.i=2;s.p=1;

六、题目描述:
1. int swap(int *x,int *y)
{
if(x==NULL ¦ ¦ y==NULL)
return -1;
*x += *y;
*y = *x- *y;
*x -= *y;
return 1;
}
请改错,溢出已经考虑,不是错误
2.
void foo(int *x, int *y)
{
*x += *y;
*x += *y;
}
void fun(int *x, int *y)
{
*x += 2 * (*y);
}
问两个函数是否等价,能否互换
解答:第一题的函数是交换。但假如考虑x, y都是指向同一个变量,结果是这个变量的值为0.
第二题的两个函数是有区别的,也考虑x,y是指向同一个变量.这样第一个函数的结果是这个变量的4倍.但第二个函数的结果是变量的3倍.

C++笔试二

给定九个数,例如:1,3,3,5,6,7,8,8,9计算出这九个数的排列的种数。需要考虑重复情况,如果给定9个1,则只有一种结果。
限制:不能使用stl库
要求:完成函数 unsigned int foo(unsigned int *arr);
输入算法代码,并给出算法复杂度分析。

分析:

#include <cstdlib>
#include <iostream>

using namespace std;
unsigned int foo(unsigned int *arr)
{
unsigned int p[] ={1,2,6,24,120,720,5040,40320,362880};
unsigned int i,j,c,s=p[8];//first the number is p99
for(i = 0; i < 7; i++)
for(j = i+1; j < 8; j++)
{
if(arr[i]>arr[j]) //swap two number
{
arr[i]^=arr[j];
arr[j]^=arr[i];
arr[i]^=arr[j];
}
}
i = 0;
c = 0;
while(i<8)
{
j = i+1;
while(arr[i]==arr[j])//compute the number of the repetition
{
c++;
j++;
}
s/=p[c];
c=0;
i=j;
}
return s;
}

int main()
{
unsigned int a[]={1,3,3,5,6,7,8,8,9};
cout<<"The number of permutation is:"<<foo(a)<<endl;
system("pause");
return 0;
}
还可以改进排序那部分。

转一个经典的题目:

给一个天平,问如何用3次把这个小球找出来
并且求出这个小球是比其他的轻还是重
将12个球分别编号为a1,a2,a3.......a10,a11,a12.
第一步:将12球分开3拨,每拨4个,a1~a4第一拨,记为b1, a5~a8第2拨,记为b2,其余第3拨,记为b3;
第二步:将b1和b2放到天平两盘上,记左盘为c1,右为c2;这时候分两中情况:

1.c1和c2平衡,此时可以确定从a1到a8都是常球;然后把c2拿空,并从c1上拿下a4,从a9到a12四球里随便取三球,假设为a9到a11,放到c2上。此时c1上是a1到a3,c2上是a9到a11。从这里又分三种情况:
A:天平平衡,很简单,说明没有放上去的a12就是异球,而到此步一共称了两次,所以将a12随便跟11个常球再称一次,也就是第三次,马上就可以确定a12是重还是轻;
B:若c1上升,则这次称说明异球为a9到a11三球中的一个,而且是比常球重。取下c1所有的球,并将a8放到c1上,将a9取下,比较a8和a11(第三次称),如果平衡则说明从c2上取下的a9是偏重异球,如果不平衡,则偏向哪盘则哪盘里放的就是偏重异球;
C:若c1下降,说明a9到a11里有一个是偏轻异球。次种情况和B类似,所以接下来的步骤照搬B就是;

2.c1和c2不平衡,这时候又分两种情况,c1上升和c1下降,但是不管哪种情况都能说明a9到a12是常球。这步是解题的关键。也是这个题最妙的地方。
A:c1上升,此时不能判断异球在哪盘也不能判断是轻还是重。取下c1中的a2到a4三球放一边,将c2中的a5和a6放到c1上,然后将常球a9放到c2上。至此,c1上是a1,a5和a6,c2上是a7,a8和a9。此时又分三中情况:
1)如果平衡,说明天平上所有的球都是常球,异球在从c1上取下a2到a4中。而且可以断定异球轻重。因为a5到a8都是常球,而第2次称的时候c1是上升的,所以a2到a4里必然有一个轻球。那么第三次称就用来从a2到a4中找到轻球。这很简单,随便拿两球放到c1和c2,平衡则剩余的为要找球,不平衡则哪边低则哪个为要找球;
2)c1仍然保持上升,则说明要么a1是要找的轻球,要么a7和a8两球中有一个是重球(这步懂吧?好好想想,很简单的。因为a9是常球,而取下的a2到a4肯定也是常球,还可以推出换盘放置的a5和a6也是常球。所以要么a1轻,要么a7或a8重)。至此,还剩一次称的机会。只需把a7和a8放上两盘,平衡则说明a1是要找的偏轻异球,如果不平衡,则哪边高说明哪个是偏重异球;
3)如果换球称第2次后天平平衡打破,并且c1降低了,这说明异球肯定在换过来的a5和a6两求中,并且异球偏重,否则天平要么平衡要么保持c1上升。确定要找球是偏重之后,将a5和a6放到两盘上称第3次根据哪边高可以判定a5和a6哪个是重球;
B:第1次称后c1是下降的,此时可以将c1看成c2,其实以后的步骤都同A,所以就不必要再重复叙述了。至此,不管情况如何,用且只用三次就能称出12个外观手感一模一样的小球中有质量不同于其他11球的偏常的球。而且在称的过程中可以判定其是偏轻还是偏重。

3.U2 合唱团在17分钟内得赶到演唱会场,途中必需跨过一座桥,四个人从桥的同一端出发,你得帮助他们到达另一端,天色很暗,而他们只有一只手电筒。一次同时最多可以有两人一起过桥,而过桥的时候必须持有手电筒,所以就得有人把手电筒带来带去,来回桥两端。手电筒是不能用丢的方式来传递的。四个人的步行速度各不同,若两人同行则以较慢者的速度为准。Bono需花1分钟过桥,Edge需花2分钟过桥,Adam需花 5分钟过桥,Larry需花10分钟过桥。他们要如何在17分钟内过桥呢?(有个同济的学生写文章说他当时在微软面试时就是碰到了这道题,最短只能做出在19分钟内过桥,微软的人对他讲这样的结果已经是不错的了!)
A点到 B 点
1 和2 过去 2 分钟 2
2 过来 4 分钟 2+2=4
10和 5过去 14分钟 4+10=14
1 过来 15 分钟 14+1=15
1 和2 过去 17 分钟 15+2=17

第一组
1.烧一根不均匀的绳,从头烧到尾总共需要1个小时。现在有若干条材质相同的绳子,问如何用烧绳的方法来计时一个小时十五分钟呢?
ans:三根绳,开始的时候,第一根点燃两端,第二根点燃一端,第三根不点。第一根绳烧完(30分钟)后,点燃第二根绳的另一端,第二根只要15分钟就可以烧完了,第二根绳烧完(45分钟)后,点燃第三根绳子两端,第三根绳烧完(1小时15分)后,计时完成

2.你有一桶果冻,其中有黄色、绿色、红色三种,闭上眼睛抓取同种颜色的两个。抓取多少个就可以确定你肯定有两个同一颜色的果冻?

3.如果你有无穷多的水,一个3公升的提捅,一个5公升的提捅,两只提捅形状上下都不均匀,问你如何才能准确称出4公升的水?

4.一个岔路口分别通向诚实国和说谎国。来了两个人,已知一个是诚实国的,另一个是说谎国的。诚实国永远说实话,说谎国永远说谎话。现在你要去说谎国,但不知道应该走哪条路,需要问这两个人。请问应该怎么问?

5.12个球一个天平,现知道只有一个和其它的重量不同,问怎样称才能用三次就找到那个球。13个呢?(注意此题并未说明那个球的重量是轻是重,所以需要仔细考虑)

6.在9个点上画10条直线,要求每条直线上至少有三个点?

7.在一天的24小时之中,时钟的时针、分针和秒针完全重合在一起的时候有几次?都分别是什么时间?你怎样算出来的?

8.怎么样种植4棵树木,使其中任意两棵树的距离相等?

  第二组

1.为什么下水道的盖子是圆的?

2.中国有多少辆汽车?

3.将汽车钥匙插入车门,向哪个方向旋转就可以打开车锁?

4.如果你要去掉中国的34个省(含自治区、直辖市和港澳特区及台湾省)中的任何一个,你会去掉哪一个,为什么?

5.多少个加油站才能满足中国的所有汽车?

6.想象你站在镜子前,请问,为什么镜子中的影象可以颠倒左右,却不能颠倒上下?

7.为什么在任何旅馆里,你打开热水,热水都会瞬间倾泻而出?

8.你怎样将Excel的用法解释给你的奶奶听?

9.你怎样重新改进和设计一个ATM银行自动取款机?

10.如果你不得不重新学习一种新的计算机语言,你打算怎样着手来开始?

11.如果你的生涯规划中打算在5年内受到奖励,那获取该项奖励的动机是什么?观众是谁?

12.如果微软告诉你,我们打算投资五百万美元来启动你的投资计划,你将开始什么样商业计划?为什么?

13.如果你能够将全世界的电脑厂商集合在一个办公室里,然后告诉他们将被强迫做一件事,那件事将是什么?

第三组

1.你让工人为你工作7天,回报是一根金条,这个金条平分成相连的7段,你必须在每天结束的时候给他们一段金条。如果只允许你两次把金条弄断,你如何给你的工人付费?

2.有一辆火车以每小时15公里的速度离开北京直奔广州,同时另一辆火车每小时20公里的速度从广州开往北京。如果有一只鸟,以30公里每小时的速度和两辆火车同时启动,从北京出发,碰到另一辆车后就向相反的方向返回去飞,就这样依次在两辆火车之间来回地飞,直到两辆火车相遇。请问,这只鸟共飞行了多长的距离?

3.你有四个装药丸的罐子,每个药丸都有一定的重量,被污染的药丸是没被污染的药丸的重量+1。只称量一次,如何判断哪个罐子的药被污染了?

4.门外三个开关分别对应室内三盏灯,线路良好,在门外控制开关时候不能看到室内灯的情况,现在只允许进门一次,确定开关和灯的对应关系?

5.人民币为什么只有1、2、5、10的面值?

6.你有两个罐子以及50个红色弹球和50个蓝色弹球,随机选出一个罐子,随机选出一个弹球放入罐子,怎么给出红色弹球最大的选中机会?在你的计划里,得到红球的几率是多少?

7.给你两颗6面色子,可以在它们各个面上刻上0-9任意一个数字,要求能够用它们拼出任意一年中的日期数值

  第四组

  第一题 . 五个海盗抢到了100颗宝石,每一颗都一样大小和价值连城。他们决定这么分:

  抽签决定自己的号码(1、2、3、4、5)

  首先,由1号提出分配方案,然后大家表决,当且仅当超过半数的人同意时,按照他的方案

  进行分配,否则将被扔进大海喂鲨鱼

  如果1号死后,再由2号提出分配方案,然后剩下的4人进行表决,当且仅当超过半数的人同

  意时,按照他的方案进行分配,否则将被扔入大海喂鲨鱼

  依此类推

  条件:每个海盗都是很聪明的人,都能很理智地做出判断,从而做出选择。

  问题:第一个海盗提出怎样的分配方案才能使自己的收益最大化?

  第二题 . 一道关于飞机加油的问题,已知:

  每个飞机只有一个油箱,

  飞机之间可以相互加油(注意是相互,没有加油机)

  一箱油可供一架飞机绕地球飞半圈,

  问题:

  为使至少一架飞机绕地球一圈回到起飞时的飞机场,至少需要出动几架飞机?(所有飞机从同一机场起飞,而且必须安全返回机场,不允许中途降落,中间没有飞机场)第三题.汽车加油问题

  一辆载油500升的汽车从A开往1000公里外的B,已知汽车每公里耗油量为1升,A处有无穷多的油,其他任何地点都没有油,但该车可以在任何地点存放油以备中转,问从A到B最少需要多少油

  第四题. 掷杯问题

  一种杯子,若在第N层被摔破,则在任何比N高的楼层均会破,若在第M层不破,则在任何比M低的楼层均会破,给你两个这样的杯子,让你在100层高的楼层中测试,要求用最少的测试次数找出恰巧会使杯子破碎的楼层。

  第五题. 推理游戏

  教授选出两个从2到9的数,把它们的和告诉学生甲,把它们的积告诉学生乙,让他们轮流猜这两个数

  甲说:“我猜不出”

  乙说:“我猜不出”

  甲说:“我猜到了”

  乙说:“我也猜到了”

  问这两个数是多少

  第六题. 病狗问题

  一个住宅区内有100户人家,每户人家养一条狗,每天傍晚大家都在同一个地方遛狗。已知这些狗中有一部分病狗,由于某种原因,狗的主人无法判断自己的狗是否是病狗,却能够分辨其他的狗是否有病,现在,上级传来通知,要求住户处决这些病狗,并且不允许指认他人的狗是病狗(就是只能判断自己的),过了7天之后,所有的病狗都被处决了,问,一共有几只病狗?为什么?

  第八题. 监狱里有100个房间,每个房间内有一囚犯。一天,监狱长说,你们狱房外有一电灯,你们在放风时可以控制这个电灯(熄或亮)。每天只能有一个人出来放风,并且防风是随机的。如果在有限时间内,你们中的某人能对我说:“我敢保证,现在每个人都已经至少放过一次风了。”我就放了你们!问囚犯们要采取什么策略才能被监狱长放掉?如果采用了这种策略,大致多久他们可以被释放?

第五组

1.某手机厂家由于设计失误,有可能造成电池寿命比原来设计的寿命短一半(不是冲放电时间),解决方案就是免费更换电池或给50元购买该厂家新手机的折换券。请给所有已购买的用户写信告诉解决方案。

2.一高层领导在参观某博物馆时,向博物馆馆员小王要了一块明代的城砖作为纪念,按国家规定,任何人不得将博物馆收藏品变为私有。博物馆馆长需要如何写信给这位领导,将城砖取回。

3.营业员小姐由于工作失误,将2万元的笔记本电脑以1.2万元错卖给李先生,王小姐的经理怎么写信给李先生试图将钱要回来?

4.给你一款新研制的手机,如果你是测试组的组长,你会如何测试?

5.如何为函数int atoi(const char * pstr)编写测试向量?

  第六组

1.链表和数组的区别在哪里?

2.编写实现链表排序的一种算法。说明为什么你会选择用这样的方法?

3.编写实现数组排序的一种算法。说明为什么你会选择用这样的方法?

4.请编写能直接实现char * strcpy(char * pstrDest,const char * pstrSource)函数功能的代码。

5.编写反转字符串的程序,要求优化速度、优化空间。

6.在链表里如何发现循环链接?

7.给出洗牌的一个算法,并将洗好的牌存储在一个整形数组里。

8.写一个函数,检查字符是否是整数,如果是,返回其整数值。(或者:怎样只用4行代码

9.给出一个函数来输出一个字符串的所有排列。

10.请编写实现void * malloc(int)内存分配函数功能一样的代码。

11.给出一个函数来复制两个字符串A和B。字符串A的后几个字节和字符串B的前几个字节重叠。

12.怎样编写一个程序,把一个有序整数数组放到二叉树中?

13.怎样从顶部开始逐层打印二叉树结点数据?请编程。

14.怎样把一个链表掉个顺序(也就是反序,注意链表的边界条件并考虑空链表)? --

15.请编写能直接实现int atoi(const char * pstr)函数功能的代码

-----------------------------------------------------------------------------------
第一组题答案:


2)根据抽屉原理,4个

3)3升装满;3升-〉5升(全注入);3升装满;3升-〉5升(剩1升);5升倒掉;3升-〉5升(注入1升);3升装满;3升-〉5升;完成(另:可用回溯法编程求解)

4)问其中一人:另外一个人会说哪一条路是通往诚实国的?回答者所指的那条路必然是通往说谎国的。

5)12个球:

  第一次:4,4如果平了:

  那么剩下的球中取3放左边,取3个好球放右边,称:

  如果左边重,那么取两个球称一下,哪个重哪个是次品,平的话第三个重,是次品,轻的话同理

  如果平了,那么剩下一个次品,还可根据需要称出次品比正品轻或者重

  如果不平:

  那么不妨设左边重右边轻,为了便于说明,将左边4颗称为重球,右边4颗称为轻球,剩下4颗称为好球

  取重球2颗,轻球2颗放在左侧,右侧放3颗好球和一颗轻球

  如果左边重

  称那两颗重球,重的一个次品,平的话右边轻球次品

  如果右边重

  称左边两颗轻球,轻的一个次品

  如果平

  称剩下两颗重球,重的一个次品,平的话剩下那颗轻球次品

13个球:

  第一次:4,4,如果平了

  剩5颗球用上面的方法仍旧能找出次品,只是不能知道次品是重是轻

  如果不平,同上 

6)

o o o

o o o

o o o

7)

23次,因为分针要转24圈,时针才能转1圈,而分针和时针重合两次之间的间隔显然>1小时,它们有23次重合机会,每次重合中秒针有一次重合机会,所以是23次

  重合时间可以对照手表求出,也可列方程求出

8)

  在地球表面种树,做一个地球内接的正四面体,内接点即为所求

  第二组无标准答案

  第三组

1. 分成1,2,4三段,第一天给1,第二天给2取回1,第3天给1,第4天给4取回1、2,第5天给1,第6天给2取回1,第七天给1

2. 求出火车相遇时间,鸟速乘以时间就是鸟飞行的距离

3. 四个罐子中分别取1,2,3,4颗药丸,称出比正常重多少,即可判断出那个罐子的药被污染

4. 三个开关分别:关,开,开10分钟,然后进屋,暗且凉的为开关1控制的灯,亮的为开关2控制的灯,暗且热的为开关3控制的灯

5. 因为可以用1,2,5,10组合成任何需要的货币值,日常习惯为10进制

6. 题意不理解...*_*

7. 012345 0126(9)78

  第四组都是很难的题目

  第一题:97 0 1 2 0或者 97 0 1 0 2 (提示:可用逆推法求出)

  第二题:3架飞机5架次,飞法:

ABC 3架同时起飞,1/8处,C给AB加满油,C返航,1/4处,B给A加满油,B返航,A到达1/2处,C从机场往另一方向起飞,3/4处,C同已经空油箱的A平分剩余油量,同时B从机场起飞,AC到7/8处同B平分剩余油量,刚好3架飞机同时返航。所以是3架飞机5架次。第三题:需要建立数学模型

(提示,严格证明该模型最优比较麻烦,但确实可证,大胆猜想是解题关键)

  题目可归结为求数列 an=500/(2n+1) n=0,1,2,3......的和Sn什么时候大于等于1000,解得n>6

  当n=6时,S6=977.57

  所以第一个中转点离起始位置距离为1000-977.57=22.43公里

  所以第一次中转之前共耗油 22.43*(2*7+1)=336.50升

  此后每次中转耗油500升

  所以总耗油量为7*500+336.50=3836.50升

  第四题:需要建立数学模型

  题目可归结为求自然数列的和S什么时候大于等于100,解得n>13

  第一个杯子可能的投掷楼层分别为:14,27,39,50,60,69,77,84,90,95,99,100

  第五题:3和4(可严格证明)

  设两个数为n1,n2,n1>=n2,甲听到的数为n=n1+n2,乙听到的数为m=n1*n2

  证明n1=3,n2=4是唯一解

  证明:要证以上命题为真,不妨先证n=7

1)必要性:

i) n>5 是显然的,因为n<4不可能,n=4或者n=5甲都不可能回答不知道

ii) n>6 因为如果n=6的话,那么甲虽然不知道(不确定2+4还是3+3)但是无论是2,4还是3,3乙都不可能说不知道(m=8或者m=9的话乙说不知道是没有道理的)

iii) n<8 因为如果n>=8的话,就可以将n分解成 n=4+x 和 n=6+(x-2),那么m可以是4x也可以是6(x-2)而4x=6(x-2)的必要条件是x=6即n=10,那样n又可以分解成8+2,所以总之当n>=8时,n至少可以分解成两种不同的合数之和,这样乙说不知道的时候,甲就没有理由马上说知道。

  以上证明了必要性

2)充分性

  当n=7时,n可以分解成2+5或3+4

  显然2+5不符合题意,舍去,容易判断出3+4符合题意,m=12,证毕

  于是得到n=7 m=12 n1=3 n2=4是唯一解。第六题:7只(数学归纳法证明)

1)若只有1只病狗,因为病狗主人看不到有其他病狗,必然会知道自己的狗是病狗(前提是一定存在病狗),所以他会在第一天把病狗处决。

2)设有k只病狗的话,会在第k天被处决,那么,如果有k+1只,病狗的主人只会看到k只病狗,而第k天没有人处决病狗,病狗主人就会在第k+1天知道自己的狗是病狗,于是病狗在第k+1天被处决

3)由1)2)得,若有n只病狗,必然在第n天被处决

  第八题:

  约定好一个人作为报告人(可以是第一个放风的人)

  规则如下:

1、报告人放风的时候开灯并数开灯次数

2、其他人第一次遇到开着灯放风时,将灯关闭

3、当报告人第100次开灯的时候,去向监狱长报告,要求监狱长放人......

  按照概率大约30年后(10000天)他们可以被释放

  第五组无标准答案

  第六组部分题参考答案:

4.

char * strcpy(char * pstrDest,const char * pstrSource)
{
assert((pstrDest!=NULL)&&(pstrSource!=NULL));
char * pstr=pstrDest;
while((*(pstrDest++)=*(pstrSource++))!='\0');
return pstr;
}

5.

char * strrev(char * pstr)
{
assert(pstr!=NULL);

char * p=pstr;
char * pret=pstr;
while(*(p++)!='\0');
p--;
char tmp;
while(p>pstr)
{
tmp=*p;
*(p--)=*(pstr);
*(pstr++)=tmp;
}
return pret;

百度笔试题:
IP段格式:ip1 ip2。之间以空格分开,ip形式为X.X.X.X,数据保存在文件中,文件不超过2k行,无序。现在要求编写算法去掉可重IP,可重有三种形式:包含、交叠、紧靠。

例如,文件内容为:
10.0.0.0 10.0.0.12
10.0.0.5 10.0.0.10 ( <= 包含)
10.0.0.8 10.0.0.15 ( <=交叠)
10.0.0.15 10.0.0.24 ( <=紧靠)

最后输出为:
10.0.0.0 10.0.0.24

code:
/*
**这个函数的作用是将文件中的一行对应的两个数据转换成整形的数据
**比如把10.0.0.0 10.0.0.12转换后,left=10*224,就是10.0.0.0对应的整数,每个数字对应8位,right=left+12
*/
void ParseLine( char line[], size_t length, unsigned int &left, unsignedint &right)
{
size_t i;
for( i=0; i<length; i++ )
{
if ( line[i]=='.' || line[i]==' ' )//将点变成0
{
line[i]=0;
}
}
char *p = (char*)&left;
char *num = line;
for( i=3; i<4; --i ) //size是size_t,而size_t是unsigned int,所以i=0再自减后变成了最大的整数,循环就会终止
{
// cout<<i<<",";
*(p+i) = strtol( num, &num ,10 );
cout<<static_cast<int>(*(p+i))<<",";
++num;
// cout<<num<<":";
}
cout<<endl;
p = (char*)&right;
for( i=3; i<4; --i )
{
*(p+i) = strtol( num, &num, 10 );
++num;
}
}


void UniqueSequence( vector<unsigned int> & uSeq, unsigned int left,unsigned int right )
{
size_t i, lPos=-1, rPos=-1;
for( i=0; i<uSeq.size(); i++ )
{
if( left <= uSeq.at(i) )
{
lPos = i;
break;
}
}
for( ;i<uSeq.size(); i++ )
{
if( right<=uSeq.at(i) )
{
rPos=i;
break;
}
}
if( lPos == -1 )
{
uSeq.push_back( left );
uSeq.push_back( right );
return;
}

if( lPos%2 == 0 )
{
if( uSeq.at(lPos)==left )
{
}
else
{
uSeq.insert( uSeq.begin()+lPos, left );
}
}
else
{
--lPos;
}
if( rPos == -1 )
{
uSeq.erase( uSeq.begin()+(lPos+1), uSeq.end() );
uSeq.push_back(right);
}
else if( rPos%2 == 0 )
{
if( uSeq.at(rPos)== right )
{
uSeq.erase( uSeq.begin()+(lPos+1), uSeq.begin()+(rPos+1) );
}
else
{
uSeq.erase( uSeq.begin()+(lPos+1), uSeq.begin()+rPos );
uSeq.insert( uSeq.begin()+rPos, right );
}
}
else
{
uSeq.erase( uSeq.begin()+(lPos+1), uSeq.begin()+rPos );
}
}


void PrintIP( unsigned int num )
{
char *p = (char*)&num;
for( size_t i=3;i>0; --i)
{
cout<< (int)p[i]<<".";
}
cout<<(int)p[0];
}

#define MAX_BUFFER_LENGTH 100
int main()
{
unsigned int left, right;
char buffer[MAX_BUFFER_LENGTH];
ifstream infile( "test.txt" );
if( infile.fail() )
{
return 0;
}
vector<unsigned int> uSeq;
while( infile.getline(buffer, MAX_BUFFER_LENGTH) )
{
ParseLine(buffer, strlen(buffer), left, right);
// cout<<left<<","<<right<<endl;
UniqueSequence( uSeq, left, right );
for( size_t i=0; i<uSeq.size(); i+=2 )
{
PrintIP(uSeq.at(i) );
cout<<" ";
PrintIP(uSeq.at(i+1));
cout<<endl;
}
cout<<endl;
}
for( size_t i=0; i<uSeq.size(); i+=2 )
{
PrintIP(uSeq.at(i) );
cout<<" ";
PrintIP(uSeq.at(i+1));
cout<<endl;
}
return 0;
}

/*long strtol( const char *nptr,char **endptr, intbase),其中nptr是以NULL结尾字符串,endptr是字符串停止扫描的地方(Pointer tocharacter that stops scan),strtol returns the value represented in thestringnptr,Thestrtol function converts nptr to a long. strtolstops reading the string nptr at the first character it cannot recognize aspart of a number. This may be the terminating null character, or it may be thefirst numeric character greater than or equal to base.
string ="-10110134932This stopped it";
l = strtol( string, &stopstring, 10 );
printf( "string = %s", string );
printf(" strtol = %ld", l );
printf(" Stopped scan at: %s", stopstring );
string = "10110134932";
printf( "string = %s\n", string );
/* Convert string using base 2, 4, and 8: */
for( base = 2; base <= 8; base *= 2 )
{
/* Convert the string: */
ul = strtoul( string, &stopstring, base );
printf( " strtol = %ld (base %d)\n", ul, base );
printf( " Stopped scan at: %s\n", stopstring );
}
打印的结果是:
string = -10110134932This stopped it strtol = -2147483647 Stopped scan at: Thisstopped itstring = 10110134932
strtol = 45 (base 2)
Stopped scan at: 34932
strtol = 4423 (base 4)
Stopped scan at: 4932
strtol = 2134108 (base 8)
Stopped scan at: 932
*/

5.如果存在两个变量:a和b,不使用“if”、“?:”、 “switch”和其它的判断语句,找出两个数中的最大值。
答案:( ( a + b ) + abs( a - b ) ) / 2

6. 写一个函数找出一个整数数组中,第二大的数(microsoft)
const int MINNUMBER = -32767 ;
int find_sec_max( int data[] , int count)
{
int maxnumber = data[0] ;
int sec_max = MINNUMBER ;
for ( int i = 1 ; i < count ; i++)
{
if ( data[i] > maxnumber )
{
sec_max = maxnumber ;
maxnumber = data[i] ;
}
else
{
if ( data[i] > sec_max )
sec_max = data[i] ;
}
}
return sec_max ;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值