您的位置:首页 > 编程语言 > C语言/C++

c++ 一些笔试题

2016-04-27 14:05 405 查看
#include<iostream>
#include<math.h>
#include<string.h>
using namespace std;

//奶牛生子:一只幼年奶牛第4年可生下第一只奶牛 以后每年生一只
//现有一只幼年奶牛 20年后 共有多少只奶牛

int CowNum(int size)
{
int* year = new int[size];
memset(year, 0, size*sizeof(int));
year[0] = 1;
int count = 0;
for (int i = 0; i < size; ++i)
{
if (i >= 4-1 )
{
year[i] = year[i - 1] + year[i - 3];
}
}
for (int i = 0; i < size; ++i)
count += year[i];
return count;

delete year;
}

int CowNum1(int year)
{
int newCow1 = 1;//1岁 牛  开始有1只
int newCow2 = 0;//2岁 牛
int newCow3 = 0;//三岁 牛
int newCow4 = 0;//四岁 牛  成年牛
//int newCow5 = 0;//将题意理解成第5年牛开始生  则加个5岁牛数量
int oldCow = 0;//可生崽 牛
int count = 0; //总数
for (int yearcnt = 2; yearcnt <= year; ++yearcnt)//默认牛是1岁 第一次进去牛 2岁
{
//newCow5 = newCow4;
newCow4 = newCow3; //3岁牛长 4岁
oldCow += newCow4;
newCow3 = newCow2;
newCow2 = newCow1;//一岁牛 长2岁
newCow1 = oldCow;//1岁牛 为可生崽牛 的数量
count = oldCow + newCow1+newCow2+newCow3;//总数为 成年牛 + 1 2 3岁牛
//count = oldCow + newCow1 + newCow2 + newCow3+newCow4; //如果是5岁开始生
//总数为 成年牛 + 1 2 3 4岁牛
}
return count;
}
//一串珠子 有M<=10种颜色 n颗 求最小的含所有颜色的子串
//逻辑复杂的一道题

void AllColorBead(char* bead, int colorNum)//bead 珠子串 colorNum 颜色数
{
char* head,* str=bead; //head 最短子串头  str 循环变量
int clrNum = 0 ,beadCnt=0,tmpCnt=1000000,tmpClrNum=-1;
char colorArr[128] = { 0 };//用来判断每种颜色是否第一次出现 来区分颜色数是否+1
while (*str!='\0')
{
if (*(str + 1) != *str) //如果相连的颜色一样直接跳过
{
char* tmp = str; //记录str 如果该子串满足要求 head=str
while ((*tmp)!='\0')
{

if (colorArr[*tmp] == 0)//颜色第一次出现 clrNum++
{
++clrNum;
++colorArr[*tmp];
}
//if (clrNum == colorNum) //告诉珠子颜色数逻辑
//{
//	if (tmpCnt > beadCnt)//如果该子串满足要求 head = str 跳出循环
//	{
//		tmpCnt = beadCnt;
//		head = str;
//	}
//	break;
//}
if (tmpClrNum==clrNum)//不告诉珠子颜色数 第一次需完全遍历 求出颜色数
break;

++beadCnt;
++tmp;
}
if (tmpCnt > beadCnt&&clrNum>=tmpClrNum)//如果该子串满足要求 head = str 跳出循环
{
tmpCnt = beadCnt;
tmpClrNum = clrNum;//不告诉珠子颜色数需加条件
head = str;
}
clrNum = 0; //每次检索子串结束  计数器制零
beadCnt = 0;
memset(colorArr, 0, 128 * sizeof(char));
}
str++; //跳刀下一个子串
}
for (int i = 0; i <= tmpCnt; ++i)//输出子串
cout << *(head + i);
cout << endl;

}

//n*n的 回字形 蛇形 数组 按行输出
// eg: n=3
// 1 2 3
// 8 9 4
// 7 6 5
void SnakeArr(int n)
{
int* arr = new int[n*n]; //储存数组
int type = 0;//写入数组类型 0 从左向右 1 从上往下 2 从右往左 3从下往上
int  num = 1;//输入数组值  1---n*n
int  gap = 0;//每行输出跨度
int i = 0, j = 0;//数组下标
while (num <= n*n)//num自加到n*n时说明 全填满了 结束循环

{
if (type == 0)//从左向右 写入数组
{
for (int index = i + gap; i < n - gap&&num <= n*n; ++i)
arr[i+j*n] = num++;
++type;//横行写入数组完成 类型+1 变竖行
++j;//j+1到下一行
}
if (type ==1)//从上到下
{
--i;//i退到 最外层处
for (int index = j + gap; j< n - gap&&num <= n*n; ++j)
arr[i + j*n] = num++;
++type;
--i; //i退到最外层-1处
}
if (type == 2)//从右到左
{
--j;//j退到未写入最外层
for (int index = i - gap; i >= gap&&num <= n*n; --i)
arr[i + j*n] = num++;
++type;
++i;//i到左边未遍历最外层
}
if (type == 3)//从下道上
{
--j;//j退到未写入最外层
for (int index = n - gap; j > gap&&num <= n*n; --j)
arr[i + j*n] = num++;
++j;//j退到未写入最外层
++i;//i到左边未遍历最外层
type = 0;//写入方向 类型 重新置1
}
gap++;//四个方向 都写入完成  跨度+1

}
for (int index = 0; index < n*n; ++index)
cout << arr[index] << ' ';
cout << endl;
delete arr;
}

//在一个字符串中 删除多余字符后 找到最长的 回文字符串长度
//eg:abbedbba  结果 abbebba
//逻辑庞大 十分复杂 网上好像有高端算法

int PlalindromeNum(char* str,int start,int end)
{
if (*str == 0)//判断 指针有效性
return 0;
int count = 0;//当前回文字符串的字符数
int bigCnt = 1;//最大回文字符串字符数
int right = end;//临界值
while (start<end&&count!=2)//如果找到最后一个当前字符的匹配项 或者 字符串到尾 跳出循环
{							//start 与end为当前子串最两端一对相同字符
for (int i = start + 1; i <=right; ++i)
{
if (str[i] == str[start])
{
end = i;
count = 2;//有相同项 count为2
}
}
if (count != 2)//没有相同项 跳到下个字符
++start;
}
if (end - start>2)//递归 找一对相同字符中的其他相同字符数量
count += PlalindromeNum(str, start + 1, end - 1);
else if (end - start == 2)//当end-start相距为2 说明中间包含若干单独字符 count++
{
++count;

}

if (right -end>1)//如果临界值-end>1说明后面还有没有遍历的字符
{
if (bigCnt < count)//则将count 保存  置0
bigCnt = count;
count = 0;
count += PlalindromeNum(str, end+1 , right);//从子串开始继续递归找匹配字符
}
if (bigCnt < count)
bigCnt = count;//始终保持bigCnt为最长回文子串的字符数
return bigCnt;
}

////用递归实现n位的格雷码  //至今未想明白
//
//char* Gray(int n)
//{
//	char *arry = (char*)malloc(sizeof(char)*(int)pow(2, n)+1);
//	if (n =1)
//	{
//		arry[0] = '0';
//		arry[1] = '1';
//		arry[2] =0 ;
//		return arry ;
//	}
//
//	char * tmp=Gray(n - 1);
//	int j = (int)pow(2, n) - 2;
//	for (int i = 0;i<j; ++i)
//	{
//		arry[i] = tmp[i] + 0;
//		arry[j - 1 - i] = tmp[i] + 1;
//	}
//	return arry;
//}
//

//有一串珠子2种颜色(红,蓝),n个(n为奇数),有多少个蓝珠子才能确定无论什么顺序穿
//都能从不同位置的两个蓝珠子
//截断为2串,并得到一串数量为(n+1)/2(不包括这两个蓝色珠子)

//重在逻辑理解 代码简单

void pearl_num(int n)
{
if (n < 3 || n % 2 != 1)
return;
int head = 0,end=0,count=0,num=2;
for (int i = 1; i <n-2; )
{
end = i;
if (end == (n + 1) / 2)
{
printf("%d\n", num);
return;
}
if ((end - head - 1) == (n + 1) / 2 || (n - 1 - end) == (n + 1) / 2)
{
i++;
}
else if (count > 0)
{
count--;
i++;
}
else
{
num++;
count=num-2;
i = 1;
}
}
printf("无答案!\n");
}

//数字的汉子读法 0<=num<1000 例如 输入 101 输出yibailingyi
void test()
{
int num = 0;
char* a[12] = { "ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu", "shi", "bai" };

while (1)
{
int arr[3] = { 0 };
char* pinyin = ((char*)malloc(sizeof(char)*20));
scanf("%d", &num);
int tmp1 = num;
for (int i = 2; i >= 0; --i)
{
arr[i] = num % 10;
num /= 10;
}
char* tmp = pinyin;
for (int i = 0; i<3; ++i)
{
if (tmp1 == 0)
{
strcpy(pinyin, "ling\0");
pinyin += 4;
break;
}
if (i == 0)
{
if (arr[i] != 0)
{
strcpy(pinyin, a[arr[i]]);
pinyin += (int)strlen(a[arr[i]]);
strcpy(pinyin, a[11]);
pinyin += 3;
}
}
else if (i == 1)
{
if (arr[i] == 0)
{
if (arr[i - 1] == 0)
continue;
if (arr[i + 1] == 0)
break;
strcpy(pinyin, a[0]);
pinyin += 4;
}
else
{
strcpy(pinyin, a[arr[i]]);
pinyin += (int)strlen(a[arr[i]]);
strcpy(pinyin, a[10]);
pinyin += 3;
}
}
else
{
if (arr[i] != 0)
{
strcpy(pinyin, a[arr[i]]);
pinyin += (int)strlen(a[arr[i]]);

}
}
free(pinyin);
}
*pinyin = 0;
printf("%s\n", tmp);
pinyin = tmp;
}
}

//小明装装备按从左到右装  如果物品太大 (大于背包最大容量)直接丢弃,如果背包装不下
//换下个背包,前一个背包不再用,小明能装多少物品?
//n 物品数 t 背包负重  m 背包个数
//a[0]--a
被给物品质量
//

void package()
{
int m, t ,n;
int a[20] = { 0 };
int i = 0;
scanf("%d%d%d",&n,&t,&m);
while (i < n)
{
scanf("%d", &a[i++]);
}
int count = 0, tmp = t;

for (i=0; m>0 && n > 0;)
{
if (a[i] > tmp)
{
i++;
n++;
}
else if (t-a[i]>=0)
{
t -= a[i++];
++count;
--n;
}
else if (m>1)
{
--m;
t = tmp;
t -= a[i++];
++count;
--n;
}
else
{
++i;
--n;
}
}
printf("%d\n",count);
}

//将字符串 按空格 翻转 同时 将大小写互换 例:“this Is a Str”-> "sTR A iS THIS"
//默认给定字符串只含有字母与空格

void reverse_str_A(char * src)
{
char* str = (char*)malloc(sizeof(char)*(strlen(src)));//将给定字符串拷贝到可写字符数组中
strcpy(str,src);
char* tmp = str;
int i = 0;
char* out = (char*)malloc(sizeof(char)*(strlen(str) ));//生成储存处理后的字符数组
char* output = out;
while (*(tmp))//计算空格个数
{
if (*tmp++ == ' '&&*tmp!=0)//'\0'之前的不计算
++i;
}
int count = i;
int *a = (int *)malloc(sizeof(int)*i);//生成记录空格下标的数组
tmp = str;
i = 0;
int j = 0;
while (*tmp)//将空格下标记录并替换为'\0'方便拷贝
{
if (*tmp == ' ')//
{
*tmp = 0;
if (*(tmp + 1)== 0)//'\0'之前的空格直接处理  将输出数组第一个字符替换为空格 并指向下一个
{
*output = ' ';
output++;
break;
}
a[j++] = i;
}
++tmp;
++i;
}
tmp = str;
for ( j = count-1; j>=0; --j)//将分割的字符串从后向前依次写入输出字符串并将各自\0替换为空格
{
if (a[0] == 0&&j==0)
break;
strcpy(output,tmp+a[j]+1);
output += strlen(tmp + a[j]+1);
*(output++) = ' ';
}
if (a[0] == 0)//处理开始空格
tmp++;
strcpy(output, tmp );//将首字符串拷贝到尾
output += strlen(tmp );
if (a[0] == 0)//将开始的空格移到末尾
{
output[0]= ' ';
output[1] = 0;
}
i = 0;
output = out;
while (*(output+i))//依次替换大小写
{
if (*(output + i) >= 'a'&&*(output + i) <= 'z')
*(output + i) -= 32;
else if (*(output + i) >= 'A'&&*(output + i) <= 'Z')
*(output + i) += 32;
++i;
}
cout << out <<"***********"<< endl;//输出
free(out);
free(output);
free(a);
}

int main()
{
cout<<CowNum(20)<<endl;
cout << CowNum1(20) << endl;
AllColorBead("11231324566457711234567111", 7);
AllColorBead("asdccaacsdfdgfwererdfg",8);

SnakeArr(5);
char* a = "vvaabbcdcbbaaxaabbcdcbbaax";
cout << PlalindromeNum(a, 0, strlen(a)) << endl;

/*pearl_num(101);
package();*/
reverse_str_A("        This   w W w  Is str ");
/*test();*/

/*char * aa;
aa=Gray(10);
cout << aa << endl;*/
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++;笔试题