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