1 有t组数据/要测试t次
一个循环搞定
第一种,for循环
#includeint main(){ int t; scanf("%d",&t); int i; for(i=1;i<=t;i++) printf("%d ",i);//这行不用在意 return 0; }
第二种,while循环(可以省一个i)
#includeint main(){ int t; scanf("%d",&t); while(t--) printf("%d ",t);//这行不用在意 return 0;}
2 输入一串字符,回车终止
循环括号里写输入语句
#includeint main(){ char ch; while(scanf("%c",&ch),ch!=' ') printf("%c",ch);//逐个 *** 作,可以这样写,加入要字符串 *** 作,则需要用数组 return 0;}
3 输入几组数,回车分割,用EOF停止
以下是一个字符由小到大排序的问题,题目不重要,主要看输入方式
#includeint main(){ char a,b,c,temp; while(scanf("%c%c%c",&a,&b,&c)!=EOF){ getchar();//前面的scanf()在读取输入时会在缓冲区中留下一个字符' ',(输入完后按回车导致),这个getchar()用于清除缓存区这个‘ ’,否则下次输入会把‘ ’存进第一次个字符 if(a>b){ temp=a; a=b; b=temp; } if(b>c){ temp=b; b=c; c=temp; } if(a>b){ temp=a; a=b; b=temp; } printf("%c %c %c ",a,b,c); } return 0;}
4 输入一系列 *** 作指令,读入over结束。
相关指令格式:
find 329 1
copy 2 1 4
add 10 1999
rfind oq 3
insert abc 1 3
reset szuuniversity 2
copy 2 1 5
over
利用了scanf(“%s”,&string);遇到空格就停止接受的特点,先把指令前缀收进来,再写一个循环语句,遇到over就break。
char order[100][100];for (i = 0;; i++){ scanf("%s", order[i]); if (strncmp(order[i], "copy", 4) == 0) { } else if (strncmp(order[i], "add", 3) == 0) { } else if (strncmp(order[i], "find", 4) == 0) { } else if (strncmp(order[i], "rfind", 5) == 0) { } else if (strncmp(order[i], "insert", 6) == 0) { } else if (strncmp(order[i], "reset", 5) == 0) { } else if (strncmp(order[i], "over", 4) == 0) break;}
5 输入一些数,读入-1结束。
int a[50],i = 0; while(scanf("%d", &a[i++]),a[i-1]!=-1);
6 输出一个数,右对齐,空位补零。
printf("%04d ", b[i]);//输出4位数,不够4位在左边补零/*输出结果实例:0000000200042000*/
素数
主要有几种情况:
1.判断一个数是否为素数;
2.给定一个区间,找到区间中的所有素数
3.找素数并对其求和
4.……
1.1判断素数
主要有两种写法,在不同场合可能各有优劣。
第一种,利用标志量记录判断素数。(一般运用于分别判断几个数是否同时为素数之类情况)
#includeint main(){ int a,i; scanf("%d",&a);//读取待判断数 int su=0;//声明一个标志量,用它来判断以下循环是否执行完毕 for(i=2;i
第二种,利用循环控制变量的终值判断循环是否走完,进而判断素数。(此方法更加简洁,更加巧妙,而且不用考虑1不是素数的情况)
#includeint main(){ int a,i; scanf("%d",&a);//读取待判断数 for(i=2;i
1.2&1.3 找素数与求和
找素数无非就是在上一个判断素数的基础之上再加入一个循环语句,达到将区间内所有数遍历的效果,然后中间再插入一个变量求和即可。(甚至还可以计算素数个数)
#includeint main(){ int n,m,sum=0; scanf("%d%d",&n,&m);读入一个区间 int j; for(j=n;j<=m;j++) { int k; for(k=2;k
2 公因数和公倍数
主要有几种情况:
1.找两个数的最大公因数和最小公倍数;
2.求两个数之间的所有公因数;
3.题目不直接问求公因数和公倍数,但需要用到;
4.……2.1求最大公因数和最小公倍数
求最大公因数利用辗转相除法,求最小公倍数就是把两数相乘然后除以最大公因数。
#includeint main(){ int x,y; scanf("%d%d",&x,&y);//读入两个数 int a; a = x*y;//提前求乘积,由于后续辗转相除会改变x和y的值 int temp;//指定临时变量,用于两数交换 while(x%y!=0)//辗转相除 { temp = x; x = y; y = temp%y; } printf("最大公因数为%d 最小公倍数为%d ",y,a/y); return 0; }
2.2 求所有公因数
#includeint main(){ int x,y; scanf("%d%d",&x,&y);//读入一个区间 int j; for(j=1;j
3 金字塔
金字塔是常见的循环问题,本质就是双重循环,一重循环控制空格输出,一重循环控制字符输出:
1.输入行数n,输出n行金字塔
2.输入行数和字符
3.……3.1一般金字塔
#includeint main(){ int n; char ch; scanf("%d %c",&n,&ch);//输入层数和组成金字塔的字符 int j;//循环控制变量 for(j=1;j<=n;j++)//循环n层 { int blank,sym;//指定空格,字符 for(blank=j;blank
3.2 菱形
菱形就是在金字塔的基础上,增加一个判断指令,让金字塔对称打印出来。
#includeint main(){ int line; scanf("%d",&line);//输入菱形的行数 int i; for(i=1;i<=line;i++)//循环控制,逐层处理 { int n;//引入中间量n,如果行数在一半以前,正常打印三角形;行数过半,则等于关于中间线对称的那行 if(i<=(line+1)/2) n = i; else n = (line+1)-i; int k; for(k=1;k<=(line+1)/2-n;k++) { printf(" "); } for(k=1;k<=n*2-1;k++) { printf("*"); } printf(" "); } return 0; }
4 倒序和分解一个数的所有位
分享一个任意位数数字倒序的算法
倒序有些时候十分重要,比如说判断一个数是否对称,只需要把它倒序,然后比较是否相等即可。
#includeint main(){ int n,temp,m=0;//定义中间量temp,输出值m,m要初始化 scanf("%d",&n);//读入一个任意数 temp = n;//避免n值被改变,如果n值不影响后续 *** 作,这一步也不需要 while(temp) { m *= 10;//m升一位 m += temp%10;//temp给出最后一位加到m上 temp /= 10;//temp抹去最后一位 } printf("%d",m); return 0;}
我们可以用上述算法分解一个数的所有位,逆序存在一个数组中
#includeint main(){ int a,temp; scanf("%d",&a);//输入一个数a temp = a;//用变量保存a,以防后续有用 int arr[100],i=0; while(temp) { arr[i++] = temp%10; temp /= 10; } arr[i] = 10;//用10作为结束,可以是别的数,此处只是为了方便取了10; for(i=0;arr[i]!=10;i++) printf("%d ",arr[i]);//结果是从低位到高位存的 return 0;}
5 算数字位数
这是一个简单的循环,但是因为很常用,所以提一下
#includeint main(){ int a; scanf("%d",&a);//读入一个非零数 int temp,n=0;//定义中间量以免a值被改变,初始化位数n temp = a; while(temp) { temp /= 10;//除掉最后一位 n++;//位数加一 } printf("%d有%d位",a,n); return 0; }
6 三个数大小排序
#includeint main(){ int a,b,c; scanf("%d%d%d",&a,&b,&c);//读入三个数a,b,c int temp; //定义临时变量,用于交换 if(c>b)//由于要从大到小输出,所以从后面开始比较,逐步把大的换到前面来 { temp = b; b = c; c = temp; } if(b>a) { temp = a; a = b; b = temp; } if(b %d>%d",a,b,c); return 0;}
7 二进制转十进制
#includeint main(){ char ch; int a=0; while(ch=getchar(),ch!=' ')//利用字符一位一位读入二进制数 a=a*2+(ch-'0');//将十转二的算法反过来做 printf("%d ",a); return 0;}
8 自定义字符串转整数函数(10进制)
int myatoi(char s[]){ int i=0,num=0; while(s[i]) num = num*10+(s[i++]-'0'); return num; }
9 自定义整数转字符串函数(10进制)
char *myitoa(int num,char s[]){ int i=0,j=0; char t[100000]; while(num) { t[i++] = num%10+'0'; num /= 10; } t[i] = '�';//t中的数字此时是反序的 i = i-1; while(i>=0)//t中数字倒着装进s中 s[j++] = t[i--]; s[j] = '�'; return s;}
10 查找字符串子串函数
int find(char s[], char n[])//在字符串N中从左开始找寻S字符串,返回其第一次出现的第一个字符串的下标,若没有找到,返回字符串N的长度。{ int i, j = 0; for (i = 0; i < strlen(n) - strlen(s);) { for ( j = 0; j < strlen(s); j++) { if (n[i]==s[j]) i++; else break; } if (j == strlen(s))//如果子串遍历完了 return (i - j);//返回下标 else i = i - j + 1; } return strlen(n);}
11 如果题目中有非常多的字符串比对要求,可以用二维数组先装着需要比对的项,然后在用循环语句遍历,用标志量判断
以手机号前三位是否合法的比对为例
char b[][20]={"133","153","180","181","189","130","131","132","155","156","134","135","136","137","138","182","183","184",'�'}; int i,j,flag; for(i=0;i<18;i++) { if(a[0]==b[i][0]&&a[1]==b[i][1]&&a[2]==b[i][2]) flag=1; }
12 分解质因数
#includeint main(){ int a,temp; scanf("%d",&a);//输入一个数a temp = a;//用变量保存a,以防后续有用 int arr[100]={0},i,j=0; for(i=2;i*i<=temp;i++)//相当于做短除法,从2开始试,然后是3,然后是5,其中4这些非素数已经被前面的素数算过了,因此不需要判断i是否为素数了 { if(temp%i==0) { while(temp%i==0) { temp /= i; arr[j++] = i; } } } for(i=0;arr[i]!=0;i++)//我用零来判断是否结束了 printf("%d ",arr[i]);//结果是升序排列的 return 0;}
13 找到所有因数,并计数
#includeint main(){ int a,temp; scanf("%d",&a);//输入一个数a temp = a;//用变量保存a,以防后续有用 int arra[100]={0},ppa=0; int arrb[100],ppb=0; int i,cnt=0;//用于计数 for(i=1;i*i<=temp;i++) { if(temp%i==0)//找到因数i存入arra中 { arra[ppa++] = i; cnt++; if(i*i!=temp)//找到i对应的另一个因数,存进arrb组中 { arrb[ppb++] = temp/i; cnt++; } } } for(i=ppb-1;i>=0;i--)//把两列因数拼起来,为了保证升序,arrb列要倒着存进arra中 arra[ppa++] = arrb[i]; printf("该数的因子个数为%d ",cnt); for(i=0;arra[i]!=0;i++)//我用零来判断是否结束了 printf("%d ",arra[i]);//结果是升序排列的 return 0;}
14 强制转换在计算平均数中的运用
#includeint main(){ int arr[105]; int n; scanf("%d", &n); int i,sum = 0; for(i= 0; i < n; i++) { scanf("%d", &arr[i]); sum += arr[i]; } // 记得强制转换,避免整除问题 double ave = (double)sum / n; printf("average = %.3f ", ave); return 0;}
15 字符串加密问题
给定⼀个仅含⼩写的字符串,要求对每个字⺟循环位移k位后得到结果
通常做法有⼆,⼀是⽤if else语句分段处理 ‘a’ 到 ‘z’-k 的部分和 ‘z’-k+1到 ‘z’ 的部分,⼆是⾃⾏推公式
#include//第一种方法int main(){ char str[105]; int k; scanf("%s%d", str, &k);//接受一个字符串,接受单个字符向后移动k位的加密指令 int i; for(i = 0; str[i]; i++) { if(str[i] <= 'z' - k) str[i] += k; else str[i] -= (26 - k); } puts(str); return 0; }
int main()//第二种{ char str[105]; int k; scanf("%s%d", str, &k); int i; for(i = 0; str[i]; i++) str[i] = ((str[i] - 'a') + k) % 26 + 'a';//这是公式 puts(str); return 0;}
16 选择排序
选择排序的关键就是,先假设最小量的下标是第一个数,然后不断移动这个下标遍历所有,找到最小数所对应的下标后,再用互换语句把数组中的两数互换
#includeint main(){ int t; scanf("%d", &t); while (t--) { int n, a[20]; scanf("%d", &n); int i,j; for ( i = 0; i < n; i++) scanf("%d", &a[i]); int min; for (i = 0; i < n-1; i++) { min = i;//先假定当前下标为最小数的下标 for ( j = i+1; j < n; j++) if (a[min] > a[j]) min = j;//找到最小数的下标,赋给min if (min != i)//将找到的下标对应的数与当前数互换 { int temp; temp = a[i]; a[i] = a[min]; a[min] = temp; } for (j = 0; j < n; j++)//这个是输出排序过程的 if (j != n - 1) printf("%d ", a[j]); else printf("%d ", a[j]); } } return 0;}
17 冒泡排序
题目描述
输入n个数字,使用冒泡排序对其进行升序排序。
输入
测试次数T
每组测试数据格式为:数字个数n,后跟n个数字。假设n<20。
输出
对每组测试数据,输出冒泡排序的每趟排序结果
样例输入
2
5 10 4 43 1 2
10 20 123 12 2 434 54 2 45 23 -10
样例输出
4 10 1 2 43
4 1 2 10 43
1 2 4 10 43
1 2 4 10 43
20 12 2 123 54 2 45 23 -10 434
12 2 20 54 2 45 23 -10 123 434
2 12 20 2 45 23 -10 54 123 434
2 12 2 20 23 -10 45 54 123 434
2 2 12 20 -10 23 45 54 123 434
2 2 12 -10 20 23 45 54 123 434
2 2 -10 12 20 23 45 54 123 434
2 -10 2 12 20 23 45 54 123 434
-10 2 2 12 20 23 45 54 123 434
#includeint main(){ int t; scanf("%d", &t); while (t--) { int n,a[20]; scanf("%d", &n); int i,j; for (i = 0; i < n; i++) scanf("%d", &a[i]); int t;//临时量,用于交换 for (i = 0; i < n-1; i++)//一共需要遍历排n-1轮 { for (j = 1; j < n-i; j++)//每轮需要比较n-i次 { if (a[j-1]>a[j]) { t = a[j - 1]; a[j - 1] = a[j]; a[j] = t; } } for (j = 0; j < n; j++)//把每次的交换过程输出 { printf("%d", a[j]); if (j!=n-1) printf(" "); } printf(" "); } } return 0;}
18 位运算符使用,打印字符
打印一个“太”字
#includeint main(){ int big[8] = { 0x8,0x8,0x8,0x7f,0x8,0x14,0x2a,0x41 };//int的长度为32位,通过在相应位置赋值1,确定字符位置,用十六进制数赋值会方便很多 unsigned int t;//unsigned可以把符号位用上,同时确保右移的过程中左边补零而不是1,这样可以变相看做是只有一个1从左向右移动 int i, j; for ( i = 0; i < 8; i++) { t = 0x80000000;//把t的1放在最右边;如果想要把打印出来的字符进行左平移,可以删去一定数量的0,删去一个零,向左移动4位 for ( j = 0; j < 32; j++) { if ((t & big[i]) != 0)//与运算,是big[i]的二进制32位和t二进制32位的逐项比较,若均为一出现1,否则为0,最后在把所得二进制数转十进制数返回 putchar('*'); else putchar(' '); t >>= 1;//移动t的1 } printf(" "); } return 0;}
19 数塔
在讲述DP(动态规划)算法的时候,一个经典的例子就是数塔问题,它是这样描述的:
有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?
假设用二维数组存储数塔。
写函数int GetMaxSum(int num[][N],int n) ,计算含n行数据的数塔num的从顶层走到底层的最大数字之和。N为宏定义,值为100。
并根据样例编写主函数。
输入
输入数据首先包括一个整数C,表示测试实例的个数,每个测试实例的第一行是一个整数N(1 <= N <= 100),表示数塔的高度,接下来用N行数字表示数塔,其中第i行有个i个整数,且所有的整数均在区间[0,99]内。
输出
对于每个测试实例,输出可能得到的最大和,每个实例的输出占一行。
样例输入
1
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
样例输出
30
#include#define N 100 int max(int a, int b){ if (a > b) return a; else return b;} int GetMaxSum(int num[][N], int n){ int i, j; for ( i = n-2; i >=0; i--)//从倒数第二行最后一项开始 for ( j = i; j >=0; j--) num[i][j] += max(0, max(num[i + 1][j], num[i + 1][j + 1])); return num[0][0];} int main(){ int t; scanf("%d", &t); while (t--) { int n; scanf("%d", &n); int a[100][N]; int i, j; for (i = 0; i < n; i++) for (j = 0; j < i + 1; j++) scanf("%d", &a[i][j]); printf("%d ",GetMaxSum(a,n)); } return 0;}
20 递归实现逆序输出
题目描述
利用递归函数调用方式,将所输入的任意个字符,以相反顺序打印出来。输入
字符串长度和该字符串输出
逆序输出样例输入
5
12345
样例输出
54321
#includevoid change(char a[],int n){ if(n==-1) return; printf("%c", a[n--]); change(a, n);} int main(){ int n; scanf("%d ", &n); char a[100]; int i; for (i = 0; i < n; i++) scanf("%c", &a[i]); change(a,n-1); return 0;}
21 上车人数(递归)
题目描述
公共汽车从始发站(称为第1站)开出,在始发站上车的人数为a,然后到达第2站,在第2站有人上、下车,但上、下车的人数相同,因此在第2站开出时(即在到达第3站之前)车上的人数保持为a人。从第3站起(包括第3站)上、下车的人数有一定的规律:上车的人数都是前两站上车人数之和,而下车人数等于上一站上车人数,一直到终点站的前一站(第n-1站),都满足此规律。现给出的条件是:共有n个车站,始发站上车的人数为a,最后一站下车的人数是m(全部下车)。试问从C站开出时车上的人数是多少?
提示:定义函数int OnBus(int n)为第n站的上车人数。
输入
只有一行,四个整数a,n,m和x
输出
x站开出时车上的人数
样例输入
5 7 32 4
样例输出
13
#include//共有n个车站,始发站上车的人数为a,最后一站下车的人数是m(全部下车)。试问从x站开出时车上的人数是多少?int OnBus(int a,int n,int y)//第一站上车a人,第n站,第二站上车y人;这个函数算的是净上车量,也就是车上人的增长量 { if (n == 1) return a; else if (n == 2) return 0; else if (n == 3) return a; else if (n == 4) return y; else if (n >= 5) return (OnBus(a, n - 1, y) + OnBus(a, n - 2, y));} int main(){ int a, n, m, x,y; scanf("%d%d%d%d", &a, &n, &m, &x); int i, j, sum;//这道题最神奇的就是没有把y告诉你,需要先把y找到,才能进行接下来的计算 for ( y = 1;; y++)//开始找y { sum = 0; for (i = 1;i < n;i++) sum += OnBus(a, i, y); if (sum == m) //如果满足条件,y就是第二站上车人数; break; } sum = 0; for (i = 1;i <= x;i++) sum += OnBus(a, i, y); //求出第x站车上的人数 printf("%d ", sum); return 0;}
22 最长公共子串
题目描述
用函数实现以下功能:参数传入两个字符串,找出这两个字符串的最长公共子串并返回。
例:abcbdab与bdbcbdde的最长公共子串为bcbd。
假设字符串最大长度为100,且最长公共子串只有一个。
编写主函数测试上述函数,在主函数中接受字符串的输入和最长子串的输出。
输入
2个字符串
输出
最长公共子串
样例输入
What is local bus?
There are some local buses.
样例输出
local bus
#include#include void compare(char a[],char b[],char c[]){ int len_a,len_b; len_a = strlen(a); len_b = strlen(b); int i,j,matrix[len_a+1][len_b+1],max=0; for(i=0;i 欢迎分享,转载请注明来源:内存溢出
评论列表(0条)