这一篇博文将会将近期写过的部分笔试程序题汇总到这里,将会不定期的更新。、、
/**
注意下面的所有的代码将主要是c语言的形式实现,假如需要会有部分c++代码。
为啥不用其他的高级语言,原因是我不会。
这些题目基本是招聘的笔试题,有的比较基础,有的比较烧脑。
*/
/*
- 第一题
:
小Q今天在上厕所时想到了这个问题:有n个数,两两组成二元组,差的绝对值最小的有多少对呢?差的绝对值最大的呢?
输入描述:
输入包含多组测试数据。
对于每组测试数据:
N - 本组测试数据有n个数
a1,a2…an - 需要计算的数据
保证:
1<=N<=100000,0<=ai<=INT_MAX.
输出描述:
对于每组数据,输出两个数,第一个数表示差的绝对值最小的对数,第二个数表示差的绝对值最大的对数。
输入例子:
6
45 12 45 32 5 6
输出例子:
1 2
思路:先排序,在找最大最小的差值
下面是代码:
*/
#include"stdio.h"
#include"stdlib.h"
int cmp(const void *a,const void *b)
{
/*设置有小到大的排序*/
return (*(int *)a - *(int*)b);
}
int main()
{
unsigned int i,j;
unsigned int data[100000];
unsigned int max_count=0;
unsigned int min_count=0;
unsigned int max=0;
unsigned int min=0xffffffff;
unsigned int num=0;
unsigned int tmp;
unsigned int resault_max;
unsigned int resault_min;
unsigned int count;
while(scanf("%d",&num)!= EOF){
for(i=0;i<num;i++){
scanf("%d",(data+i));
}
/*
下面是用快速排序法实现的排序,对于快速排序法,其算法的复杂度为O(nlogn)比冒泡排序法复制度(O(n^2))要好,这里刚一开始使用的冒泡,由于复杂度太大,腾讯竟然提示超时。。无语。
*/
qsort(data,num,sizeof(int),cmp);
/*
在这里因为要进行多次循环,每次循环前都应该给予初值,不然将导致结果出错。
*/
resault_max=1;
resault_min=1;
max=0;
min=0xffffffff;
/*
下面是找最小值,顺便把最大差值也计算出来。
*/
for(i=0;i<num-1;i++){
tmp=data[i+1]-data[i];
if(min>tmp)
min=tmp;
if(data[i+1]==data[0])
resault_min++;
if(data[i]==data[num-1])
resault_max++;
}
/*
同样,由于多次循环 ,每次都要赋予初值
*/
count=1;
min_count=0;
/*
下面是找到差值最小的个数
个数的计算方式,将最小差值的组合个数用C(2/3)的形式计算。
*/
for(i=0;i<num-1;i++){
tmp=data[i+1]-data[i];
if(tmp==min)
count++;
else{
if(count>1)
min_count+=count*(count-1)/2;
count=1;
}
}
if(count>1)
min_count+=count*(count-1)/2;
printf("%d %d\n",min_count,resault_min*resault_max);
}
}
/*
- 第二题
:
输入任意时间,输出改时刻的下一秒:
例如输入2008年2月28日23时59分59秒,
输出为:2008年2月29日0时0分0秒。
输入一个时间,输出下一秒的时间。
例如输入2008年2月28日23时59分59秒,
输出为:2008年2月29日0时0分0秒。
*/
#include"stdio.h"
#include
#include"string.h"
#include"assert.h"
void main(int argc,int *argv[])
{
int year =atoi(argv[1]);
int month =atoi(argv[2]);
int day =atoi(argv[3]);
int hour =atoi(argv[4]);
int minute =atoi(argv[5]);
int second =atoi(argv[6]);
printf("%d:%d:%d:%d:%d:%d \n",year,month,day,hour,minute,second);
updata(&year,&month,&day,&hour,&minute,&second);
printf("%d:%d:%d:%d:%d:%d \n",year,month,day,hour,minute,second);
}
inline int updata(int *year,int *month,int *day,int *hour,int *minute,int *second)
{
*second+=1;
if(*second<60)
return 0;
else{
*second=0;
*minute+=1;
if(*minute<60)
return 0;
else{
*minute=0;
*hour +=1;
if(*hour<24)
return 0;
else{
*hour=0;
*day+=1;
switch(*month)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if(*day<32)
return 0;
else{
*day =1;
*month+=1;
if(*month<13)
return 0;
else{
*month=1;
*year+=1;
return 0;
}
}
case 4:
case 6:
case 9:
case 11:
if(*day<31)
return 0;
else{
*day =1;
*month+=1;
return 0;
}
case 2:
if((*year%4==0&&*year0!=0)||*year@0==0){
if(*day<29)
return 0;
else{
*day =1;
*month+=1;
return 0;
}
}else{
if(*day<30)
return 0;
else{
*day =1;
*month+=1;
return 0;
}
}
default:return -1;
}
}
}
}
}
/*
- 第三题:
小Q最近遇到了一个难题:把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,且不能申请额外的空间。
你能帮帮小Q吗?
输入描述:
输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000.
输出描述:
对于每组数据,输出移位后的字符串。
输入例子:
AkleBiCeilD
输出例子:
kleieilABCD
*/
#include"stdio.h"
#include"string.h"
#define MAX_LENGTH 1000
int main()
{
char data[MAX_LENGTH]={0};
char lower[MAX_LENGTH]={0};
char upper[MAX_LENGTH]={0};
/*
腾讯总是这么规定,要可以循环处理
*/
while(scanf("%s",&data)!= EOF){
int num=strlen(data);
char *p_up =upper;
char *p_low=lower;
/*
将大写小字母放到不同的数组里面
*/
for(int i=0;i<num;i++){
if(data[i]>='a'&& data[i]<='z')
*p_low++=data[i];
else
*p_up++ =data[i];
}
/*
将大小写字母数组从新复制到data数组里面
*/
num=strlen(lower);
strncpy(data,lower,num);
strncpy(data+num,upper,strlen(upper));
/*
由于前面使用了while,这里打印的时候一定要用\n,不然很可能出现莫名其妙的问题。打印完毕后要清空,以便下次循环继续使用。
*/
printf("%s\n",data);
memset(data, 0 , sizeof(data));
memset(lower, 0 , sizeof(lower));
memset(upper, 0 , sizeof(upper));
}
}
**
- 第四题
:
给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
输出需要删除的字符个数。
输入描述:
输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000.
输出描述:
对于每组数据,输出一个整数,代表最少需要删除的字符个数。
输入例子:
abcda
google
输出例子:
2
2
思路:这里确实看了没什么思路,还有看到有人提示说直接用文本比较好,非常感谢“万仓一黍”的博客:
http://www.cnblogs.com/grenet/archive/2010/06/03/1750454.html
这里使用的是Needleman/Wunsch算法 ,原理上面的博文说的很明白。
**
#include"stdio.h"
#include"math.h"
#include"string.h"
#define MAX_LENGTH 1000
#define max(n,j) ((n)>(j)?(n):(j))
int main()
{
char data[MAX_LENGTH]={0};
/*
下面这个定义一定要是int型,千万不要是char类型,当时少于255个数据还好,不过腾讯测试的时候,可能是几百个数据,用char类型的数据会导致溢出,
*/
unsigned int judge_arr[MAX_LENGTH+1][MAX_LENGTH+1]={0};
int i,j;
while(scanf("%s",data)!=EOF){
int length=strlen(data);
/*下面Needleman/Wunsch算法,进行比较文本 */
for( i=0;i<length;i++){
for(j=0;j<length;j++){
if(data[i]==data[length-1-j])
judge_arr[i+1][j+1]= judge_arr[i][j]+1;
else
judge_arr[i+1][j+1]=max(judge_arr[i][j],\
max(judge_arr[i+1][j],\
judge_arr[i][j+1]));;
}
}
/*同理,打印需要加上'\n',不然提示错误*/
printf("%d\n",length-judge_arr[length][length]);
/*为了循环测试,相互不影响,清空。*/
memset(data,0,sizeof(data));
memset(judge_arr,0,sizeof(judge_arr));
}
}
- 第五题:
拉姆刚开始学习英文单词,对单词排序很感兴趣。
如果给拉姆一组单词,他能够迅速确定是否可以将这些单词排列在一个列表中,使得该列表中任何单词的首字母与前一单词的为字母相同。
你能编写一个程序来帮助拉姆进行判断吗?
输入描述:
输入包含多组测试数据。
对于每组测试数据,第一行为一个正整数n,代表有n个单词。
然后有n个字符串,代表n个单词。
保证:
2<=n<=200,每个单词长度大于1且小于等于10,且所有单词都是由小写字母组成。
输出描述:
对于每组数据,输出”Yes”或”No”
输入例子:
3
abc
cdefg
ghijkl
4
abc
cdef
fghijk
xyz
输出例子:
Yes
No
#include"stdio.h"
#include"string.h"
#define MAX_N 200
#define MAX_LENGTH 11
int main()
{
char data[MAX_N][MAX_LENGTH]={0};
int num;
int i;
while(scanf("%d",&num)!=EOF){
for(i=0;i<num;i++)
scanf("%s",data[i]);
char *p;
char *next;
int length;
for(i=0;i<num-1;i++){
p=data[i];
next=data[i+1];
length=strlen(p);
p+=length-1;
if(*p==*next)/*相等就直接进行下次判断*/
continue;
else{
printf("No\n");
goto flag;/*错误就直接跳出*/
}
}
printf("Yeo\n");
flag:
memset(data,0,sizeof(data));
}
}
- 第六题:
题目描述
计算字符串最后一个单词的长度,单词以空格隔开。
输入描述:
一行字符串,非空,长度小于5000。
输出描述:
整数N,最后一个单词的长度。
输入例子:
hello world
输出例子:
5
#include"stdio.h"
#include"string.h"
int main(void)
{
char s[5000]={0};
//唯一要注意的就是空格的输入的问题,下面两句都可以实现。
while (scanf("%[^\n]",s)!=NULL){
//while (gets(s)!=NULL){
int num=strlen(s);
int sum=0;
int i;
for(i=num;(i>0)&&(s[i-1]!=' ');i--)
sum++;
printf("%d\n",sum);
memset(s,'\0',num);
}
return 0;
}
- 第七题:
老师想知道从某某同学当中,分数最高的是多少,现在请你编程模拟老师的询问。当然,老师有时候需要更新某位同学的成绩.
输入描述:
输入包括多组测试数据。
每组输入第一行是两个正整数N和M(0 < N <= 30000,0 < M < 5000),分别代表学生的数目和操作的数目。
学生ID编号从1编到N。
第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数代表ID为i的学生的成绩
接下来又M行,每一行有一个字符C(只取‘Q’或‘U’),和两个正整数A,B,当C为’Q’的时候, 表示这是一条询问操作,他询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少
当C为‘U’的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。
输出描述:
对于每一次询问操作,在一行里面输出最高成绩.
输入例子:
5 7
1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 4 5
U 2 9
Q 1 5
输出例子:
5
6
5
9
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
int main()
{
unsigned int N;
unsigned int M;
char *grade;
char c;
unsigned int num1,num2;
while(scanf("%d%d",&N,&M)!=EOF){
//下面这里不知为何要多申请两个字节,不然提示溢出。
grade=(char *)malloc(sizeof(char)*N+2);
for(int i=0;i<N;i++){
scanf("%d",(grade+i));
}
for(int j=0;j<M;j++){
//关键在这里,注意前面%c之前的空格,必须要加,不然%c会吧一些空格、换行符等当成字符输入。
scanf(" %c%d %d",&c,&num1,&num2);
if(c=='Q'){
int max=-1;
if(num1>num2){
int tmp=num1;
num1=num2;
num2=tmp;
}
for(int i=num1-1;i<num2;i++){
if(max<*(grade+i))
max=*(grade+i);
}
printf("%d\n",max);
}else{
*(grade+num1-1)=num2;
}
}
free(grade);
}
}
题目描述
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
class Solution {
public:
double Power(double base, int exponent) {
int num=abs(exponent);
double result = base;
if(exponent==0)
return 1;
if(base>-0.0000001&&base<0.0000001)
return 0;
else{
while(--num)
result *= base;
}
if(exponent<0)
return (double)1/result;
return result;
}
};
题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
分析:
这个主要是其中的一个要不其他数字出现的和还要多,
所以,设置计数器,当遇到相等的计数器加1,不相等的减去1.当为零的时候重新选择标本。
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if(numbers.empty())
return 0;
int i=0;
int result=numbers[0];
int count=1;
while(i<numbers.size()){
if(count == 0){
result = numbers[i];
count = 1;
}else{
if(numbers[i] == result)
count++;
else
count--;
}
i++;
}
/*
下面有个易错点,比如为何不能写成:
if(count>1)
return result;
else
return 0;
实在想不明白的话就想想 121
*/
count = 0;
while(i--){
if(result == numbers[i])
count++;
}
if(count*2>numbers.size())
return result;
else
return 0;
}
};
题目描述
统计一个数字在排序数组中出现的次数。
分析:看着就是二分法吧
class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) {
if(data.empty())
return 0;
return find_data(data,k,0,data.size());
}
int find_data(vector<int> data ,int k,int start,int end){
if (start>end)
return 0;
int middle_sit = (end+start)/2;
int middle_value = data[middle_sit];
if(middle_value == k){
int count =0;
int sit = middle_sit;
while(data[sit] == k){
count++;
if(sit==0)
break;
sit--;
}
sit = middle_sit;
while(data[sit] == k){
count++;
if(sit==data.size())
break;
sit++;
}
return (count-1);
}
if(middle_value < k)
start = middle_sit + 1;
if(middle_value > k)
end = middle_sit - 1;
return find_data(data ,k , start, end);
}
};