蓝桥杯练习

基础练习

特殊回文数(回文数、循环、条件语句)

问题描述
123321是一个非常特殊的数,它从左边读和从右边读是一样的。
输入一个正整数n, 编程求所有这样的五位和六位十进制数,满足各位数字之和等于n 。


输入格式
输入一行,包含一个正整数n。


输出格式
按从小到大的顺序输出满足条件的整数,每个整数占一行。


样例输入
52


样例输出
899998
989989
998899


数据规模和约定
1<=n<=54。



#include
int main(){
     
	int num[1000];
	int a, b, c, n, i, j;
	i = 0;
	scanf("%d", &n);
	for( a=1; a<10; a++){
     
		for( b=0; b<10; b++){
     
			for( c=0; c<10; c++){
     
				if( 2*a + 2*b + c == n){
     
					num[i] = a*10000 + b*1000 + c*100 + b*10 + a;
					i++;
				}
			}
		}
	}
	for( a=1; a<10; a++){
     
		for( b=0; b<10; b++){
     
			for( c=0; c<10; c++){
     
				if( 2*a + 2*b + 2*c == n){
     
					num[i] = a*100000 + b*10000 + c*1000 + c*100 + b*10 + a;
					i++;
				}
			}
		}
	}
	for( j=0; j<i; j++){
     
		printf("%d", num[j]);
		if( j!=i){
     
			printf("\n");
		}
	}
	return 0;
}

回文数(循环、判断、回文数)

问题描述
1221是一个非常特殊的数,它从左边读和从右边读是一样的,编程求所有这样的四位十进制数。


输出格式
按从小到大的顺序输出满足条件的四位十进制数。


#include
int main(){
     
	int hw[1000];
	int i, j, a, b, c, d;
	for( a=1; a<10; a++){
     
		for( b=0; b<10; b++){
     
			for( c=0; c<10; c++){
     
				for( d=1; d<10; d++){
     
					if( a==d && b==c){
     
						printf("%d\n",a*1000 + b*100 + c*10 + d);
					}
				}
			}
		}
	}
	return 0;
}


杨辉三角形(二维数组)

问题描述
杨辉三角形又称Pascal三角形,它的第i+1行是(a+b)i的展开式的系数。
它的一个重要性质是:三角形中的每个数字等于它两肩上的数字相加。

下面给出了杨辉三角形的前4行:

1
1 1
1 2 1
1 3 3 1
  
给出n,输出它的前n行。


输入格式
输入包含一个数n。


输出格式
输出杨辉三角形的前n行。每一行从这一行的第一个数开始依次输出,中间使用一个空格分隔。请不要在前面输出多余的空格。


样例输入
4


样例输出
1
1 1
1 2 1
1 3 3 1


数据规模与约定
1 <= n <= 34。


#include
int main(){
     
	int i, j, n;
	int a[34][34];
	scanf("%d", &n);
	a[0][0] = 1;
	for( i=1; i<n; i++){
     
		for( j=0; j<=i; j++){
     
			if( j==0 || j==i){
     
				a[i][j] = 1;
			}
			else{
     
				a[i][j] = a[i-1][j-1] + a[i-1][j];
			} 
		}
	}
	for( i=0; i<n; i++){
     
		for( j=0; j<=i; j++){
     
			printf("%d ",a[i][j]);
		}
		printf("\n");
	}
	return 0;
}

数列特征(循环、最大值、最小值、累加)

问题描述
给出n个数,找出这n个数的最大值,最小值,和。


输入格式
第一行为整数n,表示数的个数。
第二行有n个数,为给定的n个数,每个数的绝对值都小于10000。


输出格式
输出三行,每行一个整数。第一行表示这些数中的最大值,第二行表示这些数中的最小值,第三行表示这些数的和。


样例输入
5
1 3 -2 4 5


样例输出
5
-2
11


数据规模与约定
1 <= n <= 10000。


#include
int main(){
     
	int n, i, j, t;
	int sum=0;
	int a[10000];
	scanf("%d",&n);
	for( i=0; i<n; i++ ){
     
		scanf("%d", &a[i]);
	}
	for( i=0; i<n; i++ ){
     
		sum += a[i];
	}

	//冒泡排序
	for( i=0; i<n-1; i++ ){
     
		for( j=0; j<n-i-1; j++ ){
     
			if( a[j]>a[j+1] ){
     
				t = a[j];
				a[j] = a[j+1];
				a[j+1] = t;
			}
		}
	}
	printf("%d\n", a[n-1]);
	printf("%d\n", a[0]);
	printf("%d", sum);

	return 0;
}

字母图形(循环、字符串)

问题描述
利用字母可以组成一些美丽的图形,下面给出了一个例子:
ABCDEFG
BABCDEF
CBABCDE
DCBABCD
EDCBABC
这是一个5行7列的图形,请找出这个图形的规律,并输出一个n行m列的图形。


输入格式
输入一行,包含两个整数n和m,分别表示你要输出的图形的行数的列数。


输出格式
输出n行,每个m个字符,为你的图形。


样例输入
5 7


样例输出
ABCDEFG
BABCDEF
CBABCDE
DCBABCD
EDCBABC


数据规模与约定
1 <= n, m <= 26。


#include
int main(){
     
	int n, m;
	int i, j, k;
	char a[26];
	a[0] = 'A';
	for( i=1; i<26; i++ ){
     
		a[i] = a[i-1]+1;
	}
	scanf("%d %d", &n, &m);
	for( i=0; i<n; i++ ){
     
		for( j=i,k=1; j>=0 && k<=m; j--,k++){
       //加上一个变量k作为限制输出个数的条件
			printf("%c", a[j]);
		}
		for( j=1; j<m-i; j++ ){
     
			printf("%c", a[j]);
		}
		printf("\n");
	}
	return 0;
}

01字串(循环)

问题描述
对于长度为5位的一个01串,每一位都可能是0或1,一共有32种可能。它们的前几个是:
00000
00001
00010
00011
00100
请按从小到大的顺序输出这32种01串。


输入格式
本试题没有输入。


输出格式
输出32行,按从小到大的顺序每行一个长度为5的01串。


样例输出
00000
00001
00010
00011
<以下部分省略>


方法一:

#include
int main(){
     
	int i, j, k, m, n;
	for( i=0; i<2; i++){
     
		for( j=0; j<2; j++ ){
     
			for( k=0; k<2; k++ ){
     
				for( m=0; m<2; m++ ){
     
					for( n=0; n<2; n++ ){
     
						printf("%d%d%d%d%d\n", i,j,k,m,n);
					}
				}
			}
		}
	}
	return 0;
}

方法二:可以直接打印输出32行。

算法训练

大小写转换(数组操作、字符串输入)

问题描述
编写一个程序,输入一个字符串(长度不超过20),然后把这个字符串内的每一个字符进行大小写变换,即将大写字母变成小写,小写字母变成大写,然后把这个新的字符串输出。


输入格式
输入一个字符串,而且这个字符串当中只包含英文字母,不包含其他类型的字符,也没有空格。


输出格式
输出经过转换后的字符串。


样例输入
AeDb


样例输出
aEdB


锦囊:
怎么输入一个字符串以回车键结束?
gets()函数用来从标准输入设备(键盘)读取字符串直到换行符结束,但换行符会被丢弃,然后在末尾添加’\0’字符。其调用格式为:gets(s);其中s为字符串变量(字符串数组名或字符串指针)。
gets(s)函数与scanf("%s",s)相似,但不完全相同,使用scanf("%s",s)函数输入字符串时存在一个问题,就是如果输入了空格会认为字符串结束,空格后的字符将作为下一个输入项处理,但gets()函数将接收输入的整个字符串直到遇到换行为止。

#include
int main(){
     
	int i;
	char str[100];
	gets(str);
	for( i=0; str[i]!='\0'; i++){
        //不能用双引号"\0"
		if( str[i]>=65 && str[i]<=90 ){
     
			str[i] = str[i]+32;
		}
		else if( str[i]>=97 && str[i]<=122 ){
     
			str[i] = str[i]-32;
		}
	}
	puts(str);
	return 0;
}

加法运算(指针)

你的表妹正在学习整数的加法,请编写一个程序来帮助她学习。该程序调用了一个函数GetTwoInts,由它来返回两个从键盘读入的100以内的整数,然后计算这两个整数之和,并把答案显示出来。要求:在主函数中不能使用scanf等函数直接输入这两个整数,而必须通过调用GetTwoInts函数来完成,在GetTwoInts函数中可以使用scanf函数。另外,由于该函数必须同时返回两个整数,因此不能采用函数返回值的方式,而必须采用指针的方法来实现。


输入格式:输入只有一行,即两个100以内的整数。


输出格式:输出只有一行,即这两个整数之和。


样例输入
4 7


样例输出
11


#include

void GetTwoInts( int *a, int *b, int *sum);

int main(){
     
	int a, b;
	int sum;
	GetTwoInts(&a, &b, &sum);  //运算符 & 的作用是获得变量的地址
	printf("%d", sum);
	return 0;
}

void GetTwoInts( int *a, int *b, int *sum){
       //指针作为函数参数
	scanf("%d %d", a, b);
	*sum = *a + *b;  //都有*
}

补充:指针实现交换函数

#include

void swap(int *a, int *b);

int main(){
     
	int a, b;
	scanf("%d %d", &a, &b);
	swap(&a, &b);
	printf("%d %d", a, b);
	return 0;
}

void swap(int *a, int *b){
     
	int t;  //不是 int *c
	t = *a; 
	*a = *b;
	*b = t;
}

1的个数

资源限制
时间限制:1.0s 内存限制:256.0MB


问题描述
输入正整数n,判断从1到n之中,数字1一共要出现几次。例如1123这个数,则出现了两次1。例如15,那么从1到15之中,一共出现了8个1。


输入格式
一个正整数n


输出格式
一个整数,表示1出现的资料


样例输入
15


样例输出
8


数据规模和约定
n不超过30000


#include
int main(){
     
	int i, n, k;
	int count=0;
	int a[30000] = {
     1};  //只给a[0]赋值,后面的元素会自动赋0值
	scanf("%d", &n);
	for( i=1; i<=n; i++ ){
     
		a[i] = a[i-1]+1;
		}

	for( i=n-1; i>=0; i-- ){
     
		if( a[i]>=10000 && a[i]<=30000 ){
     
			k = a[i]/10000;
			a[i] %= 10000;
			if( k==1 ){
     
				count++;
			}
		}
		if( a[i]>=1000 && a[i]<10000 ){
     
			k = a[i]/1000;
			a[i] %= 1000;
			if( k==1 ){
     
				count++;
			}
		}
		if( a[i]>=100 && a[i]<1000 ){
     
			k = a[i]/100;
			a[i] %= 100;
			if( k==1 ){
     
				count++;
			}
		}
		if( a[i]>=10 && a[i]<100 ){
     
			k = a[i]/10;
			a[i] %= 10;
			if( k==1 ){
     
				count++;
			}
		}
		if( a[i]==1 ){
     
			count++;
		}
	}
	printf("%d", count);
	return 0;
}

大等于n的最小完全平方数

问题描述
输出大等于n的最小的完全平方数。
若一个数能表示成某个自然数的平方的形式,则称这个数为完全平方数
Tips:注意数据范围


输入格式
一个整数n


输出格式
大等于n的最小的完全平方数


样例输入
71711


样例输出
71824


数据规模和约定
n是32位有符号整数。


注意点:

  1. 此题必须用long long 类型;
  2. 要注意考虑输入为负数或0的情况;
  3. 平方根函数: double sqrt(double x);
  4. 如果题目给的取值范围较大,那么能用long就不用int, 能用long long就不用long,使用时也要注意输入输出的格式。
类型 输入 输出
int &d %d
long &ld %ld
long long &lld %lld
double &lf %lf 或 %f
  1. 蓝桥系统不支持 m = long (sqrt(n)) 的强制转换,只需要写m = sqrt(n) 让系统自动强制转换即可。

#include
#include
int main(){
     
	long long n, m;
	scanf("%lld", &n);
	if( n<=0 ){
     
		printf("0");
	}
	else{
     
		m = sqrt(n);
		if( m*m == n ){
     
			printf("%lld", n);
		}
		else{
     
			printf("%lld", (m+1)*(m+1));
		}
	}
	return 0;
}

Bit Compressor (DP,即动态规划)(未解


P0505(阶乘问题)

一个整数n的阶乘可以写成n!,它表示从1到n这n个整数的乘积。阶乘的增长速度非常快,例如,13!就已经比较大了,已经无法存放在一个整型变量中;而35!就更大了,它已经无法存放在一个浮点型变量中。因此,当n比较大时,去计算n!是非常困难的。幸运的是,在本题中,我们的任务不是去计算n!,而是去计算n!最右边的那个非0的数字是多少。
例如,5!=12345=120,因此5!最右边的那个非0的数字是2。
再如,7!=5040,因此7!最右边的那个非0的数字是4。
再如,15!= 1307674368000,因此15!最右边的那个非0的数字是8。
请编写一个程序,输入一个整数n(0


输入:7


输出:4


#include
int main(){
     
	int n;
	int i, k;
	long jc=1;
	scanf("%d", &n);
	for( i=1; i<=n; i++ ){
     
		jc *= i;
		if( jc%10 != 0 ){
     
			jc %= 1000;   //只取 num 的后三位,因为n<=100,只留后三位即可
		}
		while( jc%10 == 0 ){
        //不要用if
			jc /= 10;
		}
	}
	k = jc%10;
	printf("%d", k);
	return 0;
}

图形显示(循环语句)

问题描述
编写一个程序,首先输入一个整数,例如5,然后在屏幕上显示如下的图形(5表示行数):
  * * * * *
  * * * *
  * * *
  * *
  *


#include
int main(){
     
	int n;
	int i, j;
	scanf("%d", &n);
	for( i=0; i<n; i++ ){
     
		for( j=n-i; j>0; j-- ){
     
			printf("* ");
		}
		printf("\n");
	}
	return 0;
}

二进制数数(循环、函数)

问题描述

如5的二进制为101,包含2个“1”。


输入格式
第一行包含2个数L,R


输出格式
一个数S,表示[L,R]区间内的所有数在二进制下包含的“1”的个数之和。


样例输入
2 3


样例输出
3


数据规模和约定
L<=R<=100000;


#include
int main(){
     
	int l, r;
	int i, j, k, num=0;
	scanf("%d %d", &l, &r);
	for( i=l,k=i; i<=r; i++,k=i ){
     
		while( k!=0 ){
     
			if( k%2==1 ){
     
				num++;
				}
			k /= 2;
		}
	}
	printf("%d", num);
	return 0;
}

小生物的逃逸(结构体)

问题描述
空间中有n个球,这些球不相交也不相切。有m个可以视为质点的小生物,可能在某些球内,也可能在所有球之外,但不会在球面上。问这些生物从原来的地方逃逸到所有球外面的空间,至少要经过多少层球面。


输入格式
第一行两个数n、m:表示球的数量和小生物的数量;
接下来n行每行四个整数Xi、Yi、Zi和Ri:表示一个球的三维坐标和半径;
接下来m行每行三个整数Xi、Yi、Zi:表示一个生物的坐标。


输出格式
一行m个数:表示每个小生物逃逸时至少经过的球面数。


样例输入
2 2
0 0 0 2
0 0 0 4
0 0 1
0 0 3


样例输出
2 1


数据规模和约定
1<=n、m<=100,|Xi|、|Yi|、|Zi|<=10000,1<=Ri<=10000;
数据保证所有球严格不接触,小生物都不在球面上。


思路:
本题主要是考公式,判定小生物是在球的里面还是外面,而判定的方法是各坐标轴的差值的平方相加小于或等于球面半径的平方则为在球中,否则不在(也就不需要穿过此球表面)
(数学不好的人看到题目真的一脸懵逼,但为了训练结构,还是去网上找了解法。)

  1. pow()
    首先,要加入头文件 math.h ,其次pow(x,y);其作用是计算x的y次方,x、y及函数值都是double型 。
  2. double型:scanf()时占位符只能用%lf; printf()时可以用%lf,也可以用%f。

#include
#include

struct point{
     
	int x;
	int y;
	int z;
};

struct sphere{
     
	int x;
	int y;
	int z;
	int r;
};

int main(){
     
	int n, m;  //n代表球的数量,m代表小生物的数量
	int i, j, a, b, count;
	struct point p[101];
	struct sphere sp[1000];
	scanf("%d %d", &n, &m);
	for( i=0; i<n; i++ ){
     
		scanf("%d %d %d %d", &sp[i].x, &sp[i].y, &sp[i].z, &sp[i].r);
	}
	for( i=0; i<m; i++ ){
     
		scanf("%d %d %d", &p[i].x, &p[i].y, &p[i].z);
	}

	for( i=0; i<m; i++ ){
     
		count = 0;
		for( j=0; j<n; j++ ){
     
			a = pow(p[i].x-sp[j].x, 2) + pow(p[i].y-sp[j].y, 2) + pow(p[i].z-sp[j].z, 2);
			b = pow(sp[j].r, 2);
			if( a<=b ){
       //说明该质点在球中
				count++;
			}
		}
		printf("%d ", count);
	}
	return 0;
}

According to Bartjens(枚举、表达式、dfs)(未解

问题描述
计算器和计算机的大量普及也有其弊端。即便是受过专业技术训练的学生们也很可能缺乏计算能力。由于电脑的大量使用,很多人无法心算出78这样的算式,甚至是用纸和笔也算不出1317。不过谁在意呢?
Bartjens教授十分在意——因为他比较传统。他决定给学生布置一些计算作业,并且不能使用电子设备。为了批改方便,他决定使得几乎所有题答案都是2000,不过不全是,否则会被学生发现然后就不仔细计算了。
不幸的是,Bartjens教授的打印机实在是太旧了,不能和新的打印机兼容。打印出了题目后,教授发现所有的符号都丢失了!例如2100-100=,被打印成了2100100=。不过,数字和等号被正确的打印了。
更糟糕的是,教授的试题原稿不见了。因此,他需要恢复出这些题原来的样子。如果答案是2000,那么2100100=可能是:
  2100-100=
  210010+0=
  210010-0=
  2100100=
  2*-100*-10+0=
Bartjen教授记得几点:

  1. 他写的数字没有前导零。例如2100100=就是不可行的。
  2. 他写0的时候不会写多个0。例如2*1000+000=就是不可行的。
  3. 他只用二元运算符,不用取负。所以2*-100*-10+0=也不合法。
  4. 他只用+、-、*,不用/和括号。
  5. 这些算式按照正常的优先级顺序计算。

你需要帮助barjen教授恢复这些题目。你需要在算式中插入至少一个运算符,使得答案是2000。有多少种可能的算式呢?


输入格式
输入包含一组数据。这组数据有n个数字(1<=n<=9),后面跟着一个=号。


输出格式
输出包含若干行,每一行是一个可行的解,具体格式见样例。按字典序从小到大输出这些字符串。如果无解,输出一行IMPOSSIBLE。


样例输入
2100100=


样例输出
210010+0=
210010-0=
2100-100=


数据规模和约定
1<=n<=9



连续正整数的和(枚举)

问题描述
78这个数可以表示为连续正整数的和,1+2+3,18+19+20+21,25+26+27。
输入一个正整数 n(<=10000)
输出 m 行(n有m种表示法),每行是两个正整数a,b,表示a+(a+1)+…+b=n。
对于多种表示法,a小的方案先输出。


样例输入
78


样例输出
1 12
18 21
25 27


#include
int main(){
     
	int n;
	int i, j, sum;
	scanf("%d", &n);
	for( i=1; i<n/2+1; i++ ){
     
		j = i;   //先把i的值存起来
		sum = 0;
		while( sum<n ){
     
			sum += i;
			i++;
		}
		if( sum==n ){
     
			printf("%d %d\n", j, i-1);  //i要减1
		}
		i = j;
	}
	return 0;
}

景点游览(排序)

问题描述
小明来到一个景区游玩,但是他的时间有限,没办法逛遍所有的景点,所以他从网上下载了每个景点的评分,他希望能够使游览的景点的评分总和最高,于是他希望你帮他对于N个景点排下序。


输入格式
输入的第一行包含一个正整数N,表示N个景点。
第二行有N个正整数,表示每个景点的评分值。


输出格式
输出一行,包含N个正整数,表示N个景点的评分从大到小的排列


样例输入
4
3 2 4 1


样例输出
4 3 2 1


数据规模和约定:N<=1000,每个景点的评分<=10000。


小垃圾,求你了一定要掌握冒泡排序,理解实现过程,记清楚循环里的i,j都代表什么,初始值是什么,循环停止的条件是什么!!!写了那么多遍还要上网搜!!!

算法提高

递归输出(递归)

问题描述
编写递归函数,将组成整数的所有数字逐个输出,每个数字后面加上一个减号“-”,例如对于整数123,该函数将输出1-2-3- 。编写主函数测试该递归函数。


输入格式
输入一个整数n


输出格式
如题目要求,把n的每个数字后面加一个减号”-“输出


样例输入
一个满足题目要求的输入范例。例:
123


样例输出
与上面的样例输入对应的输出。例:
1-2-3-


数据规模和约定:
输入n>0,必须使用递归调用来实现!


递归函数
一个函数在它的函数体内调用它自身称为递归调用,这种函数称为递归函数。
弄清楚递归的逐层进入与逐层退出。

#include
void f( int n );

int main(){
     
	int n;
	scanf("%d", &n);
	f(n);
	return 0;
}

void f( int n ){
     
	if( n==0 ){
     
		return;
	}
	f(n/10);
	printf("%d-", n%10);
}

执行过程(假设输入123):

===> f (123)
===> f (12)
===> f (1)
===> f (0)
===> printf (1-) //(1%10)-
===> printf (2-) //(12%10)-
===> printf (3-) //(123%10)-

数组求和(数组)

问题描述
输入n个数,围成一圈,求连续m(m


输入格式
输入的第一行包含两个整数n, m。第二行,共n个整数。


输出格式
输出1行,包含一个整数,连续m个数之和的最大值。


样例输入
10 3
9 10 1 5 9 3 2 6 7 4


样例输出
23


数据规模和约定
0


#include
int main(){
     
	int a[1000];
	int n, m;
	int i, j, t;
	int sum=0, max=0;
	scanf("%d %d", &n, &m);
	for( i=0; i<n; i++ ){
     
		scanf("%d", &a[i]);
	}
	for( j=0; j<m; j++ ){
     
		max += a[j];
	}
	for( i=1; i<n; i++ ){
     
		for( j=i; j<i+m; j++ ){
     
			sum += a[j%n];
		}
		if( sum>max ){
     
			t = sum;
			sum = max;
			max = t;
		}
		sum = 0;  //注意 sum 要重新赋0值
	}
	printf("%d", max);
	return 0;
}

字符串顺序比较(字符函数、strcmp)

问题描述
比较两个字符串s1和s2,输出:0表示s1与s2相等;1表示s1的字母序先于s2;-1表示s1的字母序后于s2


输入格式
输入两行,第一行输入一个字符串1,第二行输入字符串2。


输出格式
输出比较的结果


样例输入
abc
abd

样例输出
1


样例输入
English
English

样例输出
0


样例输入
hello
ha

样例输出
-1


方法一:利用string.h里的 strcmp() 函数投机取巧

#include
#include
int main(){
     
	char a[1000], b[1000];
	int res;
	gets(a);
	gets(b);
	res = strcmp(a,b);
	printf("%d", -res);
	return 0;
}

方法二:

#include
int main(){
     
	char a[1000], b[1000];
	int i=0, j, res;
	gets(a);
	gets(b);
	while( a[i]==b[i] && a[i]!='\0' ){
     
		i++;
	}
	if( a[i]=='\0' && b[i]=='\0' ){
     
		res = 0;
	}
	else{
     
		res = a[i]-b[i];   // \0 的ASCII码是0
		if( res<0 ){
     
			res = 1;
		}
		else{
     
			res = -1;
		}
	}
	printf("%d",res);
	return 0;
}

说明:
但使用这种方法需要考虑大小写得问题:eg:小写得a是否比大写A先序
可是经过测试发现本题无需考虑此问题


Monday-Saturday质因子(循环)

问题描述
这个问题是个简单的与数论有关的题目,看起来似乎是“求正整数的所有质因子”,但实际上并不完全是这样。

本题中需要定义以下几个概念:

  1. Monday-Saturday数
    对于一个正整数N,如果它除以7得到的余数是1或6,则可以写成N=7k+{1,6}的形式。更形象的,我们把这样的N称作“Monday-Saturday数”,简称“MS数”。
  2. Monday-Saturday因子
    如果对于两个MS数a,b,若存在一个MS数x,使得ax=b,那么就称a是b的一个“Monday-Saturday因子”,简称“MS因子”。
  3. Monday-Saturday质数
    如果对于MS数a,满足a>1且除了1和a之外a没有其他的MS因子,那么称a是一个“Monday-Saturday质数”,简称“MS质数”。
    注:对于传统意义上的质数,若它是一个MS数,则它一定是一个MS质数。但反之不必成立,例如27,它是一个MS质数但不是传统意义上的质数。
  4. Monday-Saturday质因子
    如果对于两个MS数a,b,若满足a是b的MS因子且a是一个MS质数,那么称a是b的一个“Monday-Saturday质因子”。
    例如:27是216的一个MS质因子(216=27*8)。

问题就是,给定一个MS数N,求其所有的Monday-Saturday质因子。


输入格式
每个输入数据包含多行,每行一个整数N(保证N一定是MS数,1<N<300000)。
输入的最后一行是一个整数1(对于这一行,你不必输出任何信息)。
每个输入数据不超过100行。


输出格式
对于每个N输出一行,表示N的所有Monday-Saturday质因子,按从小到大的顺序输出。格式形如“N: p1 p2 p3 …… pk”,注意行末无多余空格。


【样例输入】
  205920
  262144
  262200
  279936
  299998
  1


【样例输出】
  205920: 6 8 13 15 20 22 55 99
  262144: 8
  262200: 6 8 15 20 50 57 69 76 92 190 230 475 575 874 2185
  279936: 6 8 27
  299998: 299998


数据规模和约定
1<N<300000,每个输入数据不超过100行。


以下代码测评结果为80分:

#include
int main(){
     
	long a[101];  //用于存储输入的数据
	long b[10000];  //存储MS数
	long c[1000];  //用于存储因子
	long d[1000];  //用于存储质因子
	int i, j, k, l;
	int n, m, q, p, count;

	for( i=0; a[i-1]!=1; i++ ){
       //a[i-1],若是a[i]会无限循环
		scanf("%ld", &a[i]);
	}

	for( i=0; a[i]!=1; i++ ){
     

		n = 0;
		for( j=0; j<=a[i]; j++ ){
       //求 0~n 之间的MS数,放在b[n]中
			if( j%7==1 || j%7==6 ){
     
				b[n] = j;
				n++;
			}
		}

		m = 0;
		for( j=0; j<=n+1; j++ ){
      //求N的因子,放在c[m]中
			for( k=0; k<=n-1; k++ ){
     
				if( b[j]*b[k] == a[i] ){
     
					c[m] = b[j];
					m++;
				}
			}
		}

		q = 0;
		for( j=0; j<m; j++ ){
       //求质因数中的MS质数
			count = 0;
			for( k=0; k<m+1; k++ ){
     
				for( l=0; l<m+1; l++ ){
     
					if( c[k]*c[l] == c[j] ){
     
						count++;
					}
				}
			}
			if( count==2 ){
     
				d[q] = c[j];
				q++;
			}
		}

		printf("%d: ", a[i]);  //注意题目中冒号后有一个空格
		for( p=0; p<q; p++ ){
     
			printf("%ld", d[p]);   //测评的时候这里漏了一个%,然后改了老半天
			if( p!=q-1 ){
     
				printf(" ");
			}
		}
		printf("\n");
	}
	return 0;
}

实现strcmp函数(指针)

问题描述
自己实现一个比较字符串大小的函数,也即实现strcmp函数。函数:int myStrcmp(char *s1,char *s2) 按照ASCII顺序比较字符串s1与s2。若s1与s2相等返回0,s1>s2返回1,s1 具体来说,两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇’\0’为止(注意’\0’值为0,小于任意ASCII字符)。如:
  “A”<“B”
  “a”>“A”
  “computer”>“compare”
  “hello”<“helloworld”


样例输出
在这里插入图片描述


数据规模和约定
字符串长度<100。


#include
#include

int myStrcmp(char *s1, char *s2);

int main(){
     
	char s1[101], s2[101];
	gets(s1);
	gets(s2);
	printf("%d", myStrcmp(s1,s2));
	return 0;
}

int myStrcmp(char *s1, char *s2){
     
	int a;
	while(1){
     
		if( *s1>*s2 ){
     
			a = 1;
			break;
		}
		else if( *s1<*s2 ){
     
			a = -1;
			break;
		}
		else if( *s1==*s2 && *s1==0 ){
     
			a = 0;
			break;
		}
		s1++;
		s2++;
	}
	return a;
}

成绩排序(结构体)(40分


成绩排序2(结构体)(未解


使用指针逆序输出(指针)



历届试题

Excel地址


斐波那契


核桃的数量


翻硬币


分巧克力


公式求值


带分数


你可能感兴趣的:(c语言)