数组训练赛题解

目录

A. JGOD?姜神!!

B. 帅气的lk学长

C. 标题就敷衍敷衍吧

D. 坤坤乘奇鸡记

E. 校门外的树

F.  lk 学长的数组打印

G. 计算矩阵

H.(因为实在不知道标题起啥了就敷衍一下)

I.   快到碗里来!!

J.  (关于实在想不到标题所以敷衍敷衍二)

K.  这是防ak?

L.  和朱学姐一样漂亮的树猪(数组)

T.  青年歌手大奖赛_评委会打分


A.JGOD?姜神!!

  该题的题意为将数组中所有小于100的数加一,然后倒着输出数组中所有的数。注意判断数组中数的大小是否小于100即可。

#include 
int a[105];
int main() {
	int n ;
	scanf("%d",&n);
	for (int i =0; i=0; i--) {
		printf("%d ",a[i]);
	}
	return 0;
}

B.帅气的lk学长

  该题的题意为输出数组每个数左边有几个数比自己的数值小,我们可以先将数据存入数组a中,然后构造一个双重循环判断每个数左边有几个数比这个数小,并将结果存入b数组,最后依次输出b数组(当然,也可以不用b数组,直接输出计数结果),具体实现原理见代码注释。

#include 
int a[105],b[105];
int main() {
	int n;
	scanf("%d",&n);
	for(int i=1; i<=n; i++) {//一个循环将数据存入数组a
		scanf("%d",&a[i]);
	}
	for(int i=1; i<=n; i++) {// 将a[i]与它左边的数一一比较 ,i的范围是1~n
		for(int j=1; j<=i-1; j++) {//a[j]为a[i]左边的数,范围是1~i-1
			if(a[j]

C.标题就敷衍敷衍吧

  如题意输出最后m个数的和即可。

#include
int a[15];
int main() {
	int m,n,sum=0;
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; i++) {
		scanf("%d",&a[i]);
	}
	for(int i=n-m+1; i<=n; i++) {
		sum+=a[i];
	}
	printf("%d",sum);
	return 0;
}

D.坤坤乘奇鸡记

  如题意输出所有奇数的乘积即可,注意多组输入。

#include
int a[100];
int main() {
	int n;
	while(scanf("%d",&n)!=EOF) {
		int sum=1;
		for(int i=1; i<=n; i++) {
			scanf("%d",&a[i]);
		}
		for(int i=1; i<=n; i++) {
			if(a[i]%2==1) {
				sum*=a[i];
			}
		}
		printf("%d\n",sum);
	}
	return 0;
}

E.校门外的树

  该题需要注意坐标0上也有一棵树,所以实际上总共有n+1棵树。该题的题意为输入M个L和R,将L和R范围之间的树拔掉。我们可以定义一个数组a,并将a[0]~a[n]赋值为1,相当于在0~n的坐标上种了一棵树。然后在输入L和R之后,将L~R之间的数组数组赋值为0,相当于将L~R之间的树给拔掉。最后遍历整个数组,记录并输出数组中剩余1的个数(相当于记录还有几棵树)即可。

#include
int a[10005];
int main() {
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=0; i<=n; i++) {
		a[i]=1;
	}
	while(m--) {
		int x,y;
		scanf("%d%d",&x,&y);
		for(int i=x; i<=y; i++)
			a[i]=0;
	}
	int sum=0;
	for(int i=0; i<=n; i++) {
		sum+=a[i];
	}
	printf("%d",sum);
	return 0;
}

F.lk 学长的数组打印

  注意判断标准即可,题中向下取整就相当于两个int类型的整除,无需特别处理。

#include
int a[1005];
int main() {
	int n,q;
	scanf("%d%d",&n,&q);
	for(int i=1; i<=n; i++) {
		scanf("%d",&a[i]);
	}
	while(q--) {
		int x,l,r;
		scanf("%d%d%d",&x,&l,&r);
		if(x==1) {
			for(int i=l; i<=r; i++) {
				a[i]*=2;
			}
		}
		if(x==2) {
			for(int i=l; i<=r; i++) {
				a[i]/=2;
			}
		}
	}
	for(int i=1; i<=n; i++) {
		printf("%d ",a[i]);
	}
	return 0;
}

G.计算矩阵

  将矩阵存入二维数组,输出前m行的和即可。

#include
int a[105][105];
int main() {
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; i++) {
		for(int j=1; j<=n; j++) {
			scanf("%d",&a[i][j]);
		}
	}
	int sum=0;
	for(int i=1; i<=m; i++) {//前m行,所以i的范围是1~m
		for(int j=1; j<=n; j++) {
			sum+=a[i][j];
		}
	}
	printf("%d",sum);
	return 0;
}

H.(因为实在不知道标题起啥了就敷衍一下)

  将数据依次存入二维数组并且双重循环输出即可,双重循环的i和j中注意j的范围即可。

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

I.快到碗里来!!

  题意为找出矩阵中绝对值最大的数并输出它的行号、列号以及这个数。在获取该数的绝对值时,我们可以添加一个头文件:#include 然后利用abs()函数即可得到该数的绝对值。题目需要的下标利用双重循环中的i和j判断更新即可。

#include
#include
int a[105][105];
int main() {
	int n,m;
	while(scanf("%d%d",&m,&n)!=EOF) {
		for(int i=1; i<=m; i++) {
			for(int j=1; j<=n; j++) {
				scanf("%d",&a[i][j]);
			}
		}
		int mx=a[1][1],x,y;
		for(int i=1; i<=m; i++) {
			for(int j=1; j<=n; j++) {
				if(abs(a[i][j])>mx) {
					mx=abs(a[i][j]);
					x=i;
					y=j;
				}
			}
		}
		printf("%d %d %d\n",x,y,a[x][y]);
	}
	return 0;
}

J.(关于实在想不到标题所以敷衍敷衍二)

  与H题类似,H题是将矩阵左上角部分的值依次打印,而该题则是求矩阵右上角部分的值的和。

#include
int a[15][15];
int main() {
	int n;
	scanf("%d",&n);
	int sum=0;
	for(int i=1; i<=n; i++) {
		for(int j=1; j<=n; j++) {
			scanf("%d",&a[i][j]);
		}
	}
	for(int i=1; i<=n; i++) {
		for(int j=1; j<=n; j++) {
			if(j>=i)sum+=a[i][j];
		}
	}
	printf("%d",sum);
	return 0;
}

K.这是防ak?

  该题的正常写法如下

#include 
int main() {
	int n;
	scanf("%d", &n);
	for (int i = 1; i <= (n + 1) / 2; i++) {//构造上菱形以及中心轴
		for (int j = 1; j <= (n + 1) / 2 - i; j++) {
			printf(" ");
		}
		for (int j = 0; j < i * 2 - 1; j++) {
			printf("*");
		}
		printf("\n");
	}
	for (int i = 1; i <= n - (n + 1) / 2; i++) { //构造下菱形
		for (int j = 1; j <= i; j++) {
			printf(" ");
		}
		for (int j = 1; j <= n -i*2; j++) {
			printf("*");
		}
		printf("\n");
	}
	return 0;
}

  但其实该题还有代码量更少的解法

  在二维空间中 i,j两点的哈夫曼距离可以表示为:
 

    d(i,j) = Math.abs( x_i{} - x_j{}) + Math.abs( y_i{} - y_j{} ) x_i{}  

(abs为取绝对值)                           

  即:横、纵坐标差值的绝对值之和

  此题可以认为是是得到中心单元的哈弗曼顿距离满足一定的条件即可打印星号,具体如下图所示:

                                数组训练赛题解_第1张图片
上图实例输入为 n = 5 的情况,使不同颜色区分各单元到中心单元的哈曼顿距离。输入奇数 n ,坐标( n/2 , n/2),表示 n*n 方阵 的中心单元。
对于满足以上条件的的任意菱形,总是会出现相似的结构。菱形即为与此 n x n 方阵中心的哈夫曼距离不超过 n/2 的所有单元的集合。
因此打印 * 的判断条件是 Math.abs(i - n/2) + Math.abs(j - n/2) <= n/2

#include 
#include
int main() {
	int n;
	scanf("%d", &n);
	int cx = n/2,cy = n/2;
	for(int i=0; i

 L.和朱学姐一样漂亮的树猪(数组)

  这个题呢,就是把一个二维数组向右旋转90°,你们想呀,如果旋转90°,那么原来的列就变成了现在的行,原来的行,就变成了现在的列。而且原来每一列的最后的元素,就旋转到了之后每行第一个元素,那么是不是我们打印数组的时候,要把原先的列倒序输出,打印成旋转过后的行。你们画个图结合代码好好想一想,如果还是想不明白,培训的时候可以举手问一下哈。不要觉得不好意思啦,弄懂才是最关键的。

#include
using namespace std;
int main() {
	int a[15][15];
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; i++) {
		for(int j=1; j<=m; j++)
			scanf("%d",&a[i][j]);
	}
	for(int i=1; i<=m; i++) {
		for(int j=n; j>=1; j--) {
			printf("%d ",a[j][i]);
		}
		printf("\n");
	}
	return 0;
}

T.青年歌手大奖赛_评委会打分

  这道题呢,就是找出最大值和最小值,然后用总和减去二者求平均值就行。那么怎么找出最大值和最小值呢?我们可以设置一个max和min变量,之后把他们和数组中所有的数进行比较,只要遇见大于max的数就更新max的值即可,min相同,只要遇见更小的数就更新min的值即可。注意要保留两位小数嗷,要定义浮点数。

#include
using namespace std;
int main() {
	int num[105];
	int n;
	while(~scanf("%d",&n)) {
		int max=0,min=1000,sum=0;
		for(int i=0; imax) max=num[i];
			if(num[i]

PS:最后俩题的题解是美丽善良的猪猪学姐写,跟前面的题解叙述风格可能有点不一样。。。

你可能感兴趣的:(算法)