OJ系统刷题 第一篇

1651 - 二维数组输出(1)

时间限制 : 1 秒

内存限制 : 128 MB

输入一个整数N,输出一个N行N列的二维矩阵,矩阵中的元素用1——N*N顺序填充。

输入

一个整数N(N<=10)

输出

输出N行N列的矩阵,元素之间用一个空格隔开,行末不要有多余的空格。

样例

输入

5

输出

1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25

 答案:

#include<stdio.h>

int main() {
	int i = 0, j = 0,num=0,k=1;
	scanf("%d", &num);
	int a[10][10] = { 0 };
	for (i = 0; i < num; i++) {
		for (j = 0; j < num; j++) {
			a[i][j] = k++;
		}
	}

	for (i = 0; i < num; i++) {
		for (j = 0; j < num; j++) {
			if (j == num - 1) {
				printf("%d\n", a[i][j]);
			}
			else {
				printf("%d ", a[i][j]);
			}
		}
	}
}

分析,这个题难度一般,就是在打印行末数据的时候有的同学容易把循环条件给整错误。

是否通过:

1652 - 二维数组输出(2)

时间限制 : 1 秒

内存限制 : 128 MB

输入一个整数N,输出一个N行N列的二维矩阵,矩阵中的元素按列用1——N*N顺序填充。

输入

一个整数N(N<=10)

输出

输出N行N列的矩阵,元素之间用一个空格隔开,行末不要有多余的空格。

样例

输入

5

输出

1 6 11 16 21
2 7 12 17 22
3 8 13 18 23
4 9 14 19 24
5 10 15 20 25

 答案:

#include<stdio.h>

int main() {
	int i = 0, j = 0,num=0,k=1;
	scanf("%d", &num);
	int a[10][10] = { 0 };
	for (i = 0; i < num; i++) {
		for (j = 0; j < num; j++) {
			a[i][j] = k++;
		}
	}

	for (i = 0; i < num; i++) {
		for (j = 0; j < num; j++) {
			if (j == num - 1) {
				printf("%d\n", a[0][i]+j*num);
			}
			else {
				printf("%d ", a[0][i]+j*num);
			}
		}
	}
}

分析:这个题是上面那个题的改版,难度加大了。仔细观察每一行的第一个元素,是二维数组第一行的元素。然后每个元素依次加  i * 列标的长度,根据此逻辑可写出代码。

是否通过:

1653 - 螺旋矩阵(难题二刷)

时间限制 : 1 秒

内存限制 : 128 MB

输入一个整数N,输出一个N行N列的二维矩阵,矩阵中的元素用1——N*N顺序螺旋填充。

输入

一个整数N(N<=10)

输出

输出N行N列的矩阵,元素之间用一个空格隔开,行末不要有多余的空格。

样例

输入

3

输出

1 2 3
8 9 4
7 6 5

答案:

#include<stdio.h>

int main() {
	int i = 0, j = 0;//i、j分别模拟数组的行坐标和列坐标
	int N = 0, k = 1, offset = 1;//N为矩阵阶数,k为赋值变量,offset为偏移量
	int arr[100][100] = { 0 };//经过测试定义太小不通过
	scanf("%d", &N);
	int startX = 0,startY=0;//每次循环的初始行坐标和列坐标
	int count = 0;
	if (N % 2 == 1) {//N为奇数时要单独处理最后一个元素
		arr[N / 2][N / 2] = N * N;
	}
	while (count < N/2) {//循环圈数为N/2次,自己动手画一下就知道了
		for (i=startX,j = startY; j < N - offset; j++) {//上行
			arr[i][j] = k++;
		}
		for (i = startX; i < N - offset; i++) {//右行
			arr[i][j] = k++;
		}
		for (; j > startY; j--) {//下行
			arr[i][j] = k++;
		}
		for (; i > startX; i--) {//左行
			arr[i][j] = k++;
		}
		//每一圈循环结束以后,要更改变量的值
		count++;
		offset++;
		startX++; 
		startY++;
	}

	//打印
	for (i = 0; i < N; i++) {
		for (j = 0; j < N; j++) {
			if (j == N - 1) {
				printf("%d\n", arr[i][j]);
			}
			else {
				printf("%d ", arr[i][j]);
			}
		}
	}
	return 0;
}

 分析:这个题目太难不小,初次再做这个题目的时候,有点摸不着头脑,就是没有清晰的逻辑结构。通过找视频学习可知,不管N是奇数还是偶数,循环的次数均为N/2,也就是转的圈数。每一次循环以后初始行坐标和列坐标要加1,而循环走的步数也要减1,因此可以用startX和startY来记录每一次循环的初始坐标,用offset来确定每一次循环的步数。整个程序分为四个部分:即上行、右行、下行、左行来处理。如果大家看这个分析有困难,建议大家先去B站看一下这个题目的分析,再来看就不难理解了。另外再做这个题目的时候,由于题目说N的范围是N<=10,因此我定义数组的范围就是10维的,但是发现有测试点不通过,改为50维的,还是不通过,直到改为100维的才通过,也就是我们平时刷题的过程中,可以把数组定义大一点,避免因部分测试点不通过的现象。

是否通过:

1654 - 蛇形矩阵 

一个整数N(N<=10)

输出

输出N行N列的矩阵,元素之间用一个空格隔开,行末不要有多余的空格。

样例

输入

3

输出

1 2 3
6 5 4
7 8 9

 答案:

#include<stdio.h>

int main() {
	int arr[100][100] = { 0 };
	int i = 0, j = 0, count = 0, k = 1; 
	int N = 0;
	scanf("%d", &N);
	int startX = 0, startY = N-1;
	while (count < N) {
		if (count % 2 == 0) {
			for (i = startX; i < N; i++) {
				arr[count][i] = k++;
			}
		}
		else {
			for (j = startY; j >= 0; j--) {
				arr[count][j] = k++;
			}
		}
		count++;
	}

	for (i = 0; i < N; i++) {
		for (j = 0; j < N; j++) {
			if (j == N - 1) {
				printf("%d\n", arr[i][j]);
			}
			else {
				printf("%d ", arr[i][j]);
			}
		}
	}
	return 0;
}

分析:这个题目和螺旋矩阵相比,难度就简单多了,就是从左到右赋值,再从右到左赋值。这个逻辑可以用一个判断该行数是奇数还是偶数来解决。当然这个题目肯定有优化的地方。

是否通过:

1671 - 奇偶位互换

时间限制 : 1 秒

内存限制 : 128 MB

给定一个长度为偶数位的0,1字符串,请编程实现串的奇偶位互换。

输入

输入包含多组测试数据。
输入的第一行是一个整数C,表示有C测试数据。
接下来是C组测试数据,每组数据输入均为0,1字符串,保证串长为偶数位(串长<=50)。
 

输出

请为每组测试数据输出奇偶位互换后的结果,每组输出占一行。

样例

输入

2
0110
1100

输出

1001
1100

答案:

#include<stdio.h>
#include<string.h>
int main()
{
    int N;
    char arr[100];
    scanf("%d\n", &N);
    while (N--)
    {
        scanf("%s", arr);
        for (int i = 0; arr[i] != '\0'; i += 2)
        {
            int temp = arr[i];
            arr[i] = arr[i + 1];
            arr[i + 1] = temp;
        }
       printf("%s\n",arr);
    }
    return 0;
}

 分析:这个题掌握它的思想即可,就是下标0和下标1互换,下标2和下标3进行互换。直到最后。

是否通过:

算法很简单,就是难在这个输入的处理。我最开始写成下面的这种情况:

#include<stdio.h>
#include<string.h>
void Exchange(char arr[][50], int N) {
    int i = 0;
    unsigned j = 0;
    for (i = 0; i < N; i++) {
        for (j = 0; j < strlen(arr[i]); j = j + 2) {
            int temp = arr[i][j];
            arr[i][j] = arr[i][j + 1];
            arr[i][j + 1] = temp;
        }
    }

}
int main() {
    char arr[1000][50] = { 0 };
    int N = 0;
    scanf("%d", &N);
    for (int i = 0; i < N; i++) {
        scanf("%s", arr[i]);
    }
    Exchange(arr, N);
    for (int i = 0; i < N; i++) {
        printf("%s\n", arr[i]);
    }
    return 0;
}

我这个代码运行结果完全没问题,但是不能通过,因为输入方式有问题,但是题目给的那个输入案例有点歧义,从这个题目我们要总结经验,虽然题目是一下子输入多组数据,但是实际上题目的意思是输入一组数据处理一组数据。而不是一下子输入多组数据,再一次性处理这些数据。从整体要吸取教训。以后那些比赛刷题都是输入一组处理一组数据。 

输入一个英文字符串(一句话),统计输入的单词个数.(自己遇到的题,挺难的,建议二刷)

代码实现:
#include <iostream>
using namespace std;
int main(void) {
	char line[10]; //'\0'就是 0
	int i = 0; // 访问字符串(字符数组)的下标
	int count = 0; //单词计数
	cout << "请输入一句话:";
	gets_s(line, sizeof(line));
	// 跳过前面的连续空格
	bool ret = false;
	while (line[i] != '\0') {
		if (line[i] != ' ' && (line[i + 1] == ' ' || line[i + 1] == '\0')) {
			count++;
			i++;
		}
		else if (line[i] == ' ') {
			i++;
		}
		else {
			i++;
		}
	}
	cout << "一共有" << count << "个单词" << endl; 
	system("pause");
	return 0;
}

这个代码别看就这几行,难度还是相当大的,首先对C++/C语言基础语法的考察,怎么输入带空格的字符串,在C++中用gets_s()函数来实现,之前的gets函数可能导致输入溢出已经被新标准C11中移除去了。在C语言中用scanf函数,即scanf("%[^\n]",str);这两个是经典的输入要掌握!!另外就是本题统计单词的思想,因为可能出现多个空格,因此要注意对多个空格的处理,简单的就一句话,只要前面是字母后面是空格,则就统计一个单词,当然也要对最后一个单词的处理,因为它后面不是空格而是结束符'\0'。然后本题就解决了。

第一篇刷题到此结束。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值