01 求第二大数
题目描述:
写一个函数找出一个整数数组中,第二大的数
代码:
#include
#define N 105
int secondMax(int a[],int n){
int Max=a[0],s_Max=-32767;
int i;
for(i=1;iMax){
s_Max=Max;
Max=a[i];
}
else if(a[i]s_Max)
s_Max=a[i];
}
}
return s_Max;
}
int main(){
int a[N];
int n,i,ans;
while(scanf("%d",&n)!=EOF){
for(i=0;i
02 计算N的阶乘
题目描述:
编程计算n!的值
代码 1 (n!在int范围内)
#include
int multi(int ans, int n){
int i;
for(i=n;i>0;i--){
ans=ans*i;
}
return ans;
}
int main(){
int n,ans;
while(scanf("%d",&n)!=EOF){
ans=1;
ans=multi(ans,n);
printf("%d\n",ans);
}
return 0;
}
代码 2 (n!不在int范围内,n在int范围内)
#include
#include
#define N 10
//大整数乘法
struct bign{
int data[1000];
int len;
};
bign multi(bign x,int y){
int carry=0,i; //carry表示进位
for(i=0;i=0;i--){
printf("%d",a.data[i]);
}
printf("\n");
}
return 0;
}
03 字符 i 首次出现的位置
题目描述:
设有一个字符串“This is a computer”,请编程求字符“i”首次出现的位置。(字符i 与字母i )
代码:
#include
#include
#include
#include
#define N 1001
int main(){
char str[N]={0},c1,c2;
int pos=-1,i;
while(gets(str)!=NULL){
printf("所输入的是:%s\n",str);
//scanf("%c",&c1);
c1=getchar();
printf("要查找的是:%c\n",c1);
getchar(); //需要吸收换行符
if(c1>='A' && c1<='Z') //issuper(cl),是-1,不是-0
c2=c1+32; //c2=tolower(c1),转换为小写
if(c1>='a' && c1<='z') //islower(cl),是-1,不是-0
c2=c1-32; //c2=toupper(c1),转换为大写
int len=strlen(str);
printf("len=%d\n",len);
for(i=0;i
04 Fibonacci数列
题目描述:
生成Fibonacci数列的前20项并输出
代码:
#include
#define N 101
int main(){
int n,i;
int a[N];
a[1]=1,a[2]=1;
while(scanf("%d",&n)!=EOF){
if(n<2 && n>0)
for(i=1;i<=n;i++)
printf("%d ",a[i]);
else{
printf("%d %d ",a[1],a[2]);
for(i=3;i<=n;i++){
a[i]=a[i-1]+a[i-2];
printf("%d ",a[i]);
}
}
printf("\n");
}
return 0;
}
05 名称排序
题目描述:
输入五个国家的名称,按字母顺序排列输出
代码:
#include
#include
#include
int main(){
char country[5][20];
char temp[20];
int i,j;
for(i=0;i<5;i++){
scanf("%s",country[i]);
}
for(i=0;i<5;i++){
for(j=i+1;j<5;j++){
if(strcmp(country[i],country[j])>0){
strcpy(temp,country[j]);
strcpy(country[j],country[i]);
strcpy(country[i],temp);
}
}
puts(country[i]);
}
return 0;
}
指针实现字符串排序
指针实现对字符串排序,输出排序后的字符串。
#include
#include
#define MAX 20
int main(){
void sort(char **p);
int i;
char **p,*pstr[5],str[5][MAX];
for(i=0;i<5;i++){
pstr[i]=str[i]; //将第i个字符串的首地址赋予指针数组pstr的第i个元素
}
printf("input 5 strings:\n");
for(i=0;i<5;i++){
scanf("%s",pstr[i]);
}
p=pstr;
sort(p);
printf("\nstrings sorted:\n");
for(i=0;i<5;i++){
printf("%s\n",pstr[i]);
}
return 0;
}
void sort(char **p){
int i,j;
char *temp;
for(i=0;i<5;i++){
for(j=i+1;j<5;j++){
if(strcmp(*(p+i),*(p+j))>0) //比较后交换地址
{
temp=*(p+i);
*(p+i)=*(p+j);
*(p+j)=temp;
}
}
}
}
06 字符串替换
题目描述:
将字符串S1中出现的所有S2都替换成S3, 并且不损坏字符串S1。函数原型为:char exchange(char S1, char S2, char S3)
代码:
#include
#include
#include
char *exchange(char *str1, char *str2, char *str3){
char*p,*q,*r,*s;
int len1,len2,len3,i=0,len; //len表示新串的长度
len1=strlen(str1);
len2=strlen(str2);
len3=strlen(str3);
p=str1;
//统计一个字符串在另一个字符串中出现次数
while((p=strstr(p,str2))!=NULL){
i++; //统计str2出现的次数
p+=len2;
}
len=len1-i*len2+i*len3;
s=r=(char *)malloc(len);//分配动态存储空间
p=str1;
while(1){
q=strstr(p,str2); //str2串是否在s1中出现,返回首次出现位置
if(q!=NULL){
i=q-p; //出现位置距离开始位置距离
strncpy(r,p,i); //先写串str1的前i个字符
r+=i;
strcpy(r,str3); //将str3写入新串
r+=len3;
p=q+len2; //将指针移到str2子串出现之后,准备下一次循环
}
else{ //表示剩余str1中已没有str2
strcpy(r,p);
break;
}
}
return s;
}
int main(){
char a[]="sabcababde",b[]="ab",c[]="efg",*d;
d=exchange(a,b,c);
printf("result= %s\n",d);
free(d);
return 0;
}
07 求自守数
题目描述:
自守数是指一个数的平方的尾数等于自身。例如,25就是—个自守数,因为252=625,末两位数为25;9376是一个自守数,因为93762=87909376.末4位数为9376。编写程序.从键盘输入整数m和n(10 思路: 如果一个自然数的平方数的尾部仍然为该自然数本身,则称其为自守数。 分析手工方式下整数平方(乘法)的计算过程,以376为例: 141376 积 代码: 08 归并排序 归并排序包括"从上往下"和"从下往上"2种方式。 从下往上的归并排序:将待排序的数列分成若干个长度为1的子数列,然后将这些数列两两合并;得到若干个长度为2的有序数列,再将这些数列两两合并;得到若干个长度为4的有序数列,再将它们两两合并;直接合并成一个数列为止。这样就得到了我们想要的排序结果。(参考下面的图片) 从上往下的归并排序:它与"从下往上"在排序上是反方向的。它基本包括3步: 相关理论:归并排序 09 快速排序-查找第K小数 题目描述: 查找一个数组的第K小的数,注意同样大小算一样大。 如 2 1 3 4 5 2 第三小数为3。 输入: 输入有多组数据。 每组输入n,然后输入n个整数(1<=n<=1000),再输入k。 输出: 输出第k小的整数。 样例输入: 样例输出: 代码: 补充:找出数组中出现次数超过一半的元素 题目:找出数组中出现次数超过一半的元素(前提是该元素一定存在) 解法1:每次删除数组中两个不同的元素,删除后,要查找的那个元素的个数仍然超过删除后的元素总数的一半 解法2:如果数据量小,可以对数组进行排序,那么数组中间的数就是出现次数超过一半的数 该题的扩展:数组中有3个元素出现的次数都超过数组元素总数N的1/4, 找出这三个元素 解法:同上,但是每次删除4个互不相同的元素,处理上比上面的稍微麻烦 补充:二分查找 二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列; 首先分为两个过程,第一就是找到了,第二个就是没找到; ①:因为这个数组是排好序的,所以将当前的比较区间的中间值与key比较,key比中间值大,则说明key可能在数组的右半部分,否则在左半部分,一次递归,知道找到这个key为止; ②:就是没找到,只要low>=high就说明没有找到,因为当if条件不满足时,无法确实mid左右两边的high和low,不满足条件return返回-1,说明没有找到; 补充:桶排序 桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。为了使桶排序更加高效,我们需要做到这两点: 同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要。 当输入的数据可以均匀的分配到每一个桶中。 当输入的数据被分配到了同一个桶中。 元素分布在桶中: 然后,元素在每个桶中排序: 补充:基数排序 基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。 基数排序有两种方法: 这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异: 10 打牌问题 题目描述: 牌只有1到9,手里拿着已经排好序的牌a,对方出牌b,用程序判断手中牌是否能够压过对方出牌。 输入: 输入有多组数据。 输出: 压过输出YES 否则NO。 样例输入: 样例输出: 代码: 11 递推数列-矩阵幂 时间限制:1 秒 内存限制:32 兆 特殊判题:否 题目描述: 给定a0,a1,以及an=pa(n-1) + qa(n-2)中的p,q。这里n >= 2。 求第k个数对10000的模。 输入: 输入包括5个整数:a0、a1、p、q、k。 输出: 第k个数a(k)对10000的模。 样例输入: 样例输出: 思路: 在按常规思路做这道题的时候,总是wrong answer或者Time Limit Exceed,这里需参考相关矩阵幂运算知识点,样例还可见《机试课程二》。 代码 1: 再次分析题目,可以发现递推式, 进而推出, 问题转化为, 这里要用到 矩阵二分乘法。 矩阵二分乘法是一种有效的快速计算矩阵幂的算法。 矩阵二分乘法通常可以将线性递推问题O(n)时间缩短到O(log(n))。 代码 2 代码 3 12 数组最大数 输入一个四行五列的矩阵,找出每列最大的两个数。(华中科技大学真题) 题目描述: 输入第一行包括一个整数n(1<=n<=1000),接下来有n个四行每行包括五个整数。代表一个四行五列的矩阵,矩阵元素全部是整数。 输出描述: 可能有多组测试数据,对于每组数据,按照样例输出的格式将每列最大的两个数输出,如果最大的两个数中的一个数在这一列中有多个相同的值,则行值取行值小的那一个。 输出时要保留原矩阵的行列顺序,即在原矩阵中行值小的,在输出矩阵中的行值依然小。 样例输入: 样例输出: 代码 13 二叉树问题 01 题目描述: 由二叉树的先序和中序遍历,得出二叉树的后序遍历。第一行输入节点的个数,第二行输入先序序列,第三行输入中序序列,输出后序序列。 输入样例: 输出样例: 代码: 02 题目描述: 给出二叉树的先序序列,实现二叉树左右子树的交换,并分别以先序、中序、后序输出 样例输入: 样例输出: 思路: 创建树: 交换操作: 首先进行判断,只要这个结点不为根结点,就会进行判断; 从根结点开始,访问一个结点就会交换结点的左右子树; 之后判断交换后的左右子树是否为空,如果左子树不为空,继续访问这个结点的左子树,进行递归调用,重复上述步骤; 如果为空,判断这个结点的右子树是否为空,不为空,进行递归调用,为空的话结束交换Exchange函数,返回上一层递归调用; 直到访问完所有结点返回main函数,进行其他操作; #include //二叉树的结点类型 //创建树 //交换左右二叉树 //先序输出交换后的二叉树 int main(){ 14 报数–链表 题目描述: 有n个人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号人。 代码 1: 代码 2(链表法) 15 栈的应用–括号匹配问题 题目描述: 在某个字符串(长度不超过 100)中有左括号、右括号和大小写字母;规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序,找到无法匹配的左括号和右括号,输出原来字符串,并在下一行标出不能匹配的括号。不能匹配的左括号用"$“标注,不能匹配的右括号用”?"标注. 输入: 输入包括多组数据,每组数据一行,包含一个字符串,只包含左右括号和大小写字母,字符串长度不超过 100。 输出: 对每组输出数据,输出两行,第一行包含原始输入字符,第二行由" " , " ? " 和 空 格 组 成 , " ","?"和空格组成," ","?"和空格组成,"“和”?"表示与之对应的左括号和右括号不能匹配。 样例输入: 样例输出: 思路: 若我们按照从左至右的顺序遍历字符串,并将遇到的所有左括号都放入堆栈中等待匹配;若在遍历过程中遇到一个右括号,由于按照从左向右的顺序遍历字符串,若此时堆栈非空,那么栈顶左括号即为与其匹配的左括号;相反,若堆栈为空,则表示在其之前不存在未被匹配的左括号,匹配失败。 代码 : 16 哈夫曼树 题目描述: 哈夫曼树,第一行输入一个数 n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即 weight,题目需要输出所有结点的值与权值的乘积之和。 输入: 输出: 输出权值。 样例输入: 样例输出: 代码: 17 define与定义函数的区别 题目:输入三个整数x,y,z,请把这三个数由小到大输出。 代码 1: 代码 2
例如:
5 x 5 = 25
76 x 76 = 5776
625 x 625 = 390625
下面代码的目的是寻找出2千万以内的所有自守数。
注意,2千万的平方已经超出了整数表达的最大范围,所以该程序使用了一个巧妙的方案。
如果我们仔细观察乘法的计算过程,就会发现实际上对乘积的尾数有贡献的环节,从而不用真正计算出整个乘积。
376 被乘数
376 乘数
2256 第一个部分积=被乘数*乘数的倒数第一位
2632 第二个部分积=被乘数乘数的倒数第二位
1128 第三个部分积=被乘数乘数的倒数第三位
本问题所关心的是积的最后三位。分析产生积的后三位的过程,可以看出,在每一次的部分积中,并不是它的每一位都会对积的后三位产生影响。#include
① 分解 – 将当前区间一分为二,即求分裂点 mid = (low + high)/2;
② 求解 – 递归地对两个子区间a[low…mid] 和 a[mid+1…high]进行归并排序。递归的终结条件是子区间长度为1。
③ 合并 – 将已排序的两个子区间a[low…mid]和 a[mid+1…high]归并为一个有序的区间a[low…high]。int atemp[100];
void merge(int a[],int low,int mid,int high){
int i=low,j=mid+1,k=0; //k是指向临时数组
while(i<=mid && j<=high){
if(a[i]
6
2 1 3 5 2 2
3
3
#include
#include
#include
规则:出牌牌型有5种
[1]一张 如4 则5…9可压过
[2]两张 如44 则55,66,77,…,99可压过
[3]三张 如444 规则如[2]
[4]四张 如4444 规则如[2]
[5]五张 牌型只有12345 23456 34567 45678 56789五个,后面的比前面的均大。
每组输入两个字符串(字符串大小不超过100)a,b。a字符串代表手中牌,b字符串代表出的牌。12233445566677 33
1122335566778899 12345
YES
YES
#include
20 1 1 14 5
8359
#include
#include
#include
2
1 2 4 9 8
-1 4 9 8 8
12 9 8 7 0
7 8 9 7 0
12 9 9 9 8
7 8 9 8 8
#include
11
7 6 9 2 5 8 3 11 1 4 10
2 9 5 6 8 7 11 3 4 10 1
2 5 9 8 6 11 10 4 1 3 7
#include
AB##C#D##
A C D B
D C A B
D C B A
#include
typedef struct tree{
char ch;
struct tree *lchild;
struct tree *rchild;
}BitTree;
BitTree *CreatTree(){
BiTree *bt;
char str;
scanf("%c",&str);
if(str==’#’)
return NULL;
else{
bt=(BiTree *)malloc(sizeof(BitTree));
bt->ch=str;
bt->lchild=CreatTree();
bt->rchild=CreatTree();
return bt;
}
}
void Exchange(BitTree *bt){
if(bt==NULL)
return ;
else{
//交换左右子树
BitTree *temp=bt->lchild;
bt->lchild=bt->rchild;
bt->rchild=temp;
Exchange(bt->lchild);
Exchange(bt->rchild);
}
}
void PreOrder(BitTree *bt){
if(bt!=NULL){
printf("%c “,bt->ch);
PreOrder(bt->lchild);
PreOrder(bt->rchild);
}
}
//中序输出交换后的二叉树
void InOrder(BitTree *bt){
if(bt!=NULL){
InOrder(bt->lchild);
printf(”%c “,bt->ch);
InOrder(bt->rchild);
}
}
//后序输出交换后的二叉树
void PostOrder(BitTree *bt){
if(bt!=NULL){
PostOrder(bt->lchild);
PostOrder(bt->rchild);
printf(”%c ",bt->ch);
}
}
BitTree *bt;
//创建二叉树
printf(“请以先序序列输入需要交换的二叉树:\n”);
bt=CreatTree();
//交换左右子树
Exchange(bt);
//先序输出
printf(“交换后以先序序列输出:\n”);
PreOrder(bt);
printf("\n");
//中序输出
printf(“交换后以中序序列输出:\n”);
InOrder(bt);
printf("\n");
//后序输出
printf(“交换后以后序序列输出:\n”);
PostOrder(bt);
printf("\n");
return 0;
}#include
#include
)(rttyy())sss)(
)(rttyy())sss)(
? ?$
#include
输入有多组数据。每组第一行输入一个数 n,接着输入 n 个叶节点(叶节点权值不超过 100,2<=n<=1000)。5
1 2 2 5 9
37
#include
#include
#include