4.数组
737. 数组替换
输入一个长度为 10 的整数数组 X[10],将里面的非正整数全部替换为 1,输出替换完成后的数组。
输入格式 输入包含 10 个整数,每个整数占一行。
输出格式 输出新数组中的所有元素,每个元素占一行。
输出格式为 X[i] = x,其中 i 为元素编号(从 0 开始),x 为元素的值。
数据范围 −100≤X[i]≤100 输入样例: 10 -9 0-4 -10 0-2 -7 7 4 输出样例: X[0] = 10 X[1] = 1 X[2] = 1 X[3] = 1 X[4] = 1 X[5] = 1 X[6] = 1 X[7] = 1 X[8] = 7 X[9] = 4
简单判断
#include<cstdio>
using namespace std;
const int N = 12;
int x, a[N];
int main()
{
for(int i = 0;i < 10;i++)
{
scanf("%d", &x);
if(x <= 0) a[i] = 1;//非正整数
else a[i] = x;
}
for(int i = 0;i < 10;i++) printf("X[%d] = %d\n", i, a[i]);
return 0;
}
条件表达式-压缩代码
#include <iostream>
#include <cstdio>
using namespace std;
int main(){
for(int i = 0; i < 10; i ++ ){
int x; cin >> x;
printf("X[%d] = %d\n", i, x <= 0 ? 1 : x);
}
return 0;
}
738. 数组填充
输入一个整数 V,输出一个长度为 10 的数组 N,数组中的第一个元素为 V,每个后续元素的值都为上一个元素的值的 2 倍。
例如,如果输入整数为 1,则数组为:1,2,4,8… 输入格式 输入一个整数 V。
输出格式 输出数组中的所有元素,每个元素占一行。
输出格式为 N[i] = x,其中 i 为元素编号(从 0 开始),x 为元素的值。
数据范围 1≤V≤50 输入样例: 1 输出样例: N[0] = 1 N[1] = 2 N[2] = 4 N[3] = 8 N[4] = 16 N[5] = 32 N[6] = 64 N[7] = 128 N[8] = 256 N[9] = 512
#include<cstdio>
using namespace std;
typedef long long int LLD;
LLD a[11], v;
int main()
{
scanf("%lld", &v); //%lld
for(int i = 0;i < 10;i++)
{
a[i] = v;
v <<= 1; // v *= 2;
}
for(int i = 0;i < 10; i++) printf("N[%d] = %lld\n", i, a[i]);
return 0;
}
739. 数组选择
输入一个长度为 100 的数组 A,请你按顺序输出其中不大于 10 的所有元素。
输入格式 输入 100 个数,每个数占一行,表示数组的所有元素的值。
每个数可能是整数也可能是浮点数。
输出格式 按顺序输出数组中的所有不大于 10 的元素,每个元素占一行。
输出格式为 A[i] = x,其中 i 为元素编号,x 为元素的值。
注意,所有的 x 均保留一位小数。
数据范围 −100≤A[i]≤100 输入样例: 0-5 63 -8.5 ... 输出样例: A[0] = 0.0 A[1] = -5.0 A[3] = -8.5 ...
#include<cstdio>
using namespace std;
const int N = 105;
double a[N];
int main()
{
for(int i = 0; i < 100; i++)
{
scanf("%lf", &a[i]); //double 用 %d ,则a[i]不会读入数据
if(a[i] <= 10.0)
printf("A[%d] = %.1lf\n", i, a[i]);
}
return 0;
}
740. 数组变换
输入一个长度为 20 的整数数组 N,将整个数组翻转,使得第一个元素成为倒数第一个元素,第二个元素成为倒数第二个元素,…,倒数第二个元素成为第二个元素,倒数第一个元素成为第一个元素。
输出翻转后的数组。
输入格式 输入包含 20 个整数,每个数占一行。
输出格式 输出新数组中的所有元素,每个元素占一行。
输出格式为 N[i] = x,其中 i 为元素编号(从 0 开始),x 为元素的值。
数据范围 −100≤N[i]≤100 输入样例: 0-5 ... 63 23 输出样例: N[0] = 23 N[1] = 63 ... N[18] = -5 N[19] = 0
#include <cstdio>
#include<algorithm>
using namespace std;
const int N = 20;
int a[N];
int main()
{
for(int i = 0; i < 20; i++) scanf("%d", &a[i]);
//for(int i = 0; i < 20; i++) printf("N[%d] = %d\n", i, a[20 - i - 1]); 下标逆序计算
reverse(a, a + 20); //函数法
for(int i = 0; i < 20; i++) printf("N[%d] = %d\n", i, a[i]);
return 0;
}
old_code
#include <bits/stdc++.h>
using namespace std;
int a[20];
int main()
{
for(int i=0; i < 20; i++)
{
cin>>a[i];
}
for(int i = 19; i >=0 ; i--)
{
printf("N[%d] = %d\n",abs(i - 19), a[i]);
}
return 0;
}
741. 斐波那契数列
输入整数 N,求出斐波那契数列中的第 N 项是多少。
斐波那契数列的第 0 项是 0,第 1 项是 1,从第 2 项开始的每一项都等于前两项之和。
输入格式 第一行包含整数 T,表示共有 T 个测试数据。
接下来 T 行,每行包含一个整数 N。
输出格式 每个测试数据输出一个结果,每个结果占一行,
结果格式为 Fib(N) = x,其中 N 为项数,x 为第 N 项的值。
数据范围 0≤N≤60 输入样例: 3 04 2 输出样例: Fib(0) = 0 Fib(4) = 3 Fib(2) = 1
DP
#include<iostream>
using namespace std;
typedef long long LL;
const int N = 65;
LL fib[N] = {0,1};
int main()
{
fib[0] = 0, fib[1] = 1;
for(int i = 2 ; i<= 60 ; i++) fib[i] = fib[i - 1] + fib[i - 2];
int T;
scanf("%d", &T);
while(T--)
{
int n;
scanf("%d", &n);
printf("Fib(%lld) = %lld\n", n, fib[n]); // LL ~~~~ scanf("%lld", )
//cout<<"Fib(" << n << ") = "<< fib[n] << endl;
}
return 0;
}
递推
#include <cstdio>
using namespace std;
typedef long long LL;
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int n;
scanf("%d", &n);
LL a = 0, b = 1, c;
for(int i = 0; i <= n; i++) //递推没有存下来时间复杂度高
{
if (i == n) printf("Fib(%d) = %lld\n", n, a); //a从第0项开始,不断往后移动, i从0开始 :a每轮为第i项
c = a + b;
a = b;
b = c;
}
}
return 0;
}
742. 最小数和它的位置
输入一个整数 N 和一个长度为 N 的整数数组 X。
请你找到数组中最小的元素,并输出它的值和下标。
注意,如果有多个最小值,则返回下标最小的那个。
输入格式 第一行包含整数 N。
第二行包含 N 个用空格隔开的整数 X[i]。
输出格式 第一行输出 Minimum value: x,其中 x 为数组元素最小值。
第二行输出 Position: y,其中 y 为最小值元素的下标(下标从 0 开始计数)。
数据范围 1<N≤1000, −1000≤X[i]≤1000 输入样例: 10 1 2 3 4 -5 6 7 8 9 10 输出样例: Minimum value: -5 Position: 4
简版
#include<cstdio>
using namespace std;
const int N = 1010;
int n;
int q[N];
int main()
{
scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d", &q[i]);
int minv = 1e4, min_idx;
for(int i = 0; i < n; i++)
if(minv > q[i])
{
minv = q[i];
min_idx = i;
}
printf("Minimum value: %d\nPosition: %d", minv, min_idx);
return 0;
}
容器版
#include<cstdio>
#include<vector>
using namespace std;
int n;
vector<int> q;
int main()
{
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
int x;
scanf("%d", &x);
q.push_back(x);
}
int minv = 1e4, min_idx;
//for(vector<int>::iterator it = q.begin() ; it != q.end() ; it++) //不好表示下标:需多一个变量
int len = q.size();
for(int i = 0; i < q.size(); i++)
if(minv > q[i])
{
minv = q[i];
min_idx = i;
}
printf("Minimum value: %d\nPosition: %d", minv, min_idx);
return 0;
}
743. 数组中的行
输入一个二维数组 M[12][12],根据输入的要求,求出二维数组中某一列的元素的平均值或元素的和。
输入格式 第一行输入整数 C,表示所求的具体列数(列数从 0 开始计数)。
第二行包含一个大写字母,若为 S,则表示需要求出第 C 列的元素的和,若为 M,则表示需要求出第 C 列的元素的平均值。
接下来 12 行,每行包含 12 个用空格隔开的浮点数,表示这个二维数组,其中第 i+1 行的第 j+1 个数表示数组元素 M[i][j]。
输出格式 输出一个数,表示所求的平均数或元素的和的值,保留一位小数。
数据范围 −100.0≤M[i][j]≤100.0 输入样例: 1 S -9.0 -2.4 -3.3 2.4 -9.7 -5.7 -5.3 6.5 -7.3 4.8 -4.1 3.9 1.6 -0.9 9.2 -7.5 1.0 -8.0 -4.1 -4.0 -0.1 -9.0 8.4 4.9 -8.2 -0.3 -5.1 -5.6 6.6 0.9 -1.0 -5.4 -2.1 -4.5 -8.7 -1.1 -4.2 6.5 -8.2 3.6 -4.6 -9.2 -1.7 6.9 -9.0 -9.8 7.7 -3.4 -8.0 5.7 4.8 0.3 -1.4 2.8 -6.3 9.3 0.3 6.3 1.5 -1.7 1.7 -0.0 9.7 -6.6 1.3 -2.0 -6.1 2.0 -7.8 -4.7 -9.1 6.0 -8.2 -1.7 9.4 -1.2 -1.0 -9.0 -7.0 -6.9 -1.6 -6.8 -6.7 1.8 4.8 1.3 -6.1 -0.6 0.5 -2.9 -6.8 1.5 5.8 3.2 0.0 7.7 6.3 1.1 4.7 7.3 7.6 5.6 0.9 9.2 1.3 -4.9 7.8 -4.9 0.5 3.5 -5.0 9.0 8.8 8.7 7.5 7.5 -9.6 -6.9 -1.6 6.9 7.8 5.6 -6.4 3.6 2.3 0.5 4.1 6.1 8.6 -9.3 2.2 -0.4 9.9 0.9 6.4 -2.8 -4.2 -7.6 0.6 9.6 3.0 0.9 5.1 4.5 输出样例: 19.3
#include<cstdio>
#include<iostream>
using namespace std;
const int N = 13;
double q[N][N]; //用到精度 : scanf的易错点就来了!!! double ---> %lf , LL ---> %lld
double sum[N];
int main()
{
int row;
char op;
//cin >> row >> op; //scanf易错 %d %c
scanf("%d %c", &row, &op);
for(int i = 0; i < 12; i++)
for(int j = 0; j < 12; j++)
{
scanf("%lf", &q[i][j]);
sum[i] += q[i][j];
}
if(op == 'S') printf("%.1lf", sum[row]); //格式输出 printf方便
else printf("%.1lf", sum[row] / 12); //压缩代码printf("%.1lf",op=='S' ? sum[row] : sum[row] / 12);
return 0;
}
y总
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int n;
char op;
double matrix[12][12];
cin >> n >> op;
for (int i = 0; i < 12; i ++ )
for (int j = 0; j < 12; j ++ )
cin >> matrix[i][j];
double s = 0;
for (int i = 0; i < 12; i ++ ) s += matrix[n][i];
if (op == 'M') s /= 12;//先求和, 如果求平均就 / 12.0
printf("%.1lf\n", s);
return 0;
}
/*简洁版
#include <iostream>
using namespace std;
int main()
{
int l;
char op;
cin >> l >> op;
double s=0;
for(int i=0;i<12;i++)
{
for(int j=0;j<12;j++)
{
double a;
cin >> a;
if(i==l) s+=a;
}
}
printf("%.1lf",op=='S' ? s : s/12);
}
*/
744. 数组中的列
输入一个二维数组 M[12][12],根据输入的要求,求出二维数组中某一列的元素的平均值或元素的和。
输入格式 第一行输入整数 C,表示所求的具体列数(列数从 0 开始计数)。
第二行包含一个大写字母,若为 S,则表示需要求出第 C 列的元素的和,若为 M,则表示需要求出第 C 列的元素的平均值。
接下来 12 行,每行包含 12 个用空格隔开的浮点数,表示这个二维数组,其中第 i+1 行的第 j+1 个数表示数组元素 M[i][j]。
输出格式 输出一个数,表示所求的平均数或元素的和的值,保留一位小数。
数据范围 −100.0≤M[i][j]≤100.0 输入样例: 1 S -9.0 -2.4 -3.3 2.4 -9.7 -5.7 -5.3 6.5 -7.3 4.8 -4.1 3.9 1.6 -0.9 9.2 -7.5 1.0 -8.0 -4.1 -4.0 -0.1 -9.0 8.4 4.9 -8.2 -0.3 -5.1 -5.6 6.6 0.9 -1.0 -5.4 -2.1 -4.5 -8.7 -1.1 -4.2 6.5 -8.2 3.6 -4.6 -9.2 -1.7 6.9 -9.0 -9.8 7.7 -3.4 -8.0 5.7 4.8 0.3 -1.4 2.8 -6.3 9.3 0.3 6.3 1.5 -1.7 1.7 -0.0 9.7 -6.6 1.3 -2.0 -6.1 2.0 -7.8 -4.7 -9.1 6.0 -8.2 -1.7 9.4 -1.2 -1.0 -9.0 -7.0 -6.9 -1.6 -6.8 -6.7 1.8 4.8 1.3 -6.1 -0.6 0.5 -2.9 -6.8 1.5 5.8 3.2 0.0 7.7 6.3 1.1 4.7 7.3 7.6 5.6 0.9 9.2 1.3 -4.9 7.8 -4.9 0.5 3.5 -5.0 9.0 8.8 8.7 7.5 7.5 -9.6 -6.9 -1.6 6.9 7.8 5.6 -6.4 3.6 2.3 0.5 4.1 6.1 8.6 -9.3 2.2 -0.4 9.9 0.9 6.4 -2.8 -4.2 -7.6 0.6 9.6 3.0 0.9 5.1 4.5 输出样例: 19.3
浮点数读入
#include<cstdio>
using namespace std;
const int N = 13;
double sum; //浮点数 - 警觉
double q[N][N];
int main()
{
int n;
char op;
scanf("%d %c", &n, &op);
for(int i = 0; i < 12; i++)
for(int j = 0; j < 12; j++)
{
scanf("%lf", &q[i][j]); //浮点数 - 警觉
if(j == n) sum += q[i][j]; //第n列的和(下标从0开始)
}
if(op == 'S') printf("%.1lf", sum);
else printf("%.1lf", sum / 12);
return 0;
}
c++版
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,i,j;
char ch;
double s,t;
cin>>n>>ch;
for(i=0;i<=11;i++)
for(j=0;j<=11;j++){
cin>>t;
if(j==n)s=s+t; //只要j等于n,就累加
}
cout<<fixed<<setprecision(1);
if(ch=='S') cout<<s;
else cout<<s/12;
//printf("%.1lf", ch == 'S' ? c : c / 12);
return 0;
}
此类题目写出对角线,就是简单的数学空间区域交集划分
745. 数组的右上半部分
输入一个二维数组 M[12][12],根据输入的要求,求出二维数组的右上半部分元素的平均值或元素的和。
右上半部分是指主对角线上方的部分,如下图所示,黄色部分为对角线,绿色部分为右上半部分:
输入格式 第一行输入一个大写字母,若为 S,则表示需要求出右上半部分的元素的和,若为 M,则表示需要求出右上半部分的元素的平均值。
接下来 12 行,每行包含 12 个用空格隔开的浮点数,表示这个二维数组,其中第 i+1 行的第 j+1 个数表示数组元素 M[i][j]。
输出格式 输出一个数,表示所求的平均数或元素的和的值,保留一位小数。
数据范围 −100.0≤M[i][j]≤100.0 输入样例: M -6.5 8.2 0.7 9.0 0.8 -4.3 0.9 -0.0 -7.9 7.1 -1.6 4.6 -9.4 -9.0 1.5 -9.0 -5.1 -0.5 -2.8 -9.1 8.0 -6.9 -5.5 -6.6 -6.8 0.3 3.8 6.1 -9.9 -9.3 8.5 8.6 5.0 6.9 -3.6 -3.0 -0.8 -1.6 -7.3 -6.7 4.4 -9.1 -9.0 1.6 0.3 -6.0 6.0 -0.8 -0.8 -6.0 -4.9 -3.9 6.4 6.2 -4.2 -0.9 7.9 1.6 -8.2 -9.2 7.8 -5.8 -5.8 -5.8 7.2 0.5 -7.9 1.2 -6.8 -9.1 0.3 -1.4 4.3 -7.2 3.5 -6.4 -9.1 -6.0 3.5 -5.1 -5.6 -6.9 -9.1 -2.1 -7.6 -7.1 0.7 -1.7 5.0 -9.0 1.4 -6.2 7.6 4.8 -7.5 4.0 -0.2 0.3 -4.2 8.4 0.7 -6.4 -2.7 3.5 -0.9 3.7 0.9 -2.7 7.1 0.1 8.4 -5.1 -7.9 -0.5 -5.3 -5.7 -4.6 9.6 -8.3 7.0 9.6 -9.8 3.3 -9.9 -6.8 6.7 3.1 1.2 -9.5 -4.3 -1.7 -9.7 1.8 5.0 8.3 -0.7 -0.9 3.2 2.5 0.5 7.3 8.3 0.3 0.9 输出样例: -1.2
注意看图【判断与数组下标关系】
图中绿色求和部分:y > x ----> j > i
绿色部分:==【下标】:倒头看:数组下标对应: y = x分界线(副对角线) , y = -x (正对角线)==
#include<cstdio>
using namespace std;
const int N = 13;
double q[N][N], sum;
int main()
{
char op;
scanf("%c\n", &op);
for(int i = 0; i < 12; i++) //一个看图误区:需翻转90度看, 对角线应该为:y = x ---> 右上半部分 : y > x
for(int j = 0; j < 12; j++)
{
scanf("%lf", &q[i][j]);
if(j > i) //【下标】:倒头看:数组下标对应: y = x分界线(副对角线) , y = -x (正对角线)
sum += q[i][j];
}
if(op == 'S') printf("%.1lf", sum);
else printf("%.1lf", sum / 66.0); //个数 11 * (11 + 1) / 2
return 0;
}
746. 数组的左下半部分
输入一个二维数组 M[12][12],根据输入的要求,求出二维数组的左下半部分元素的平均值或元素的和。
左下半部分是指主对角线下方的部分,如下图所示,黄色部分为对角线,绿色部分为左下半部分:
输入格式 第一行输入一个大写字母,若为 S,则表示需要求出左下半部分的元素的和,若为 M,则表示需要求出左下半部分的元素的平均值。
接下来 12 行,每行包含 12 个用空格隔开的浮点数,表示这个二维数组,其中第 i+1 行的第 j+1 个数表示数组元素 M[i][j]。
输出格式 输出一个数,表示所求的平均数或和的值,保留一位小数。
数据范围 −100.0≤M[i][j]≤100.0 输入样例: S 8.7 5.6 -2.0 -2.1 -7.9 -9.0 -6.4 1.7 2.9 -2.3 8.4 4.0 -7.3 -2.1 0.6 -9.8 9.6 5.6 -1.3 -3.8 -9.3 -8.0 -2.0 2.9 -4.9 -0.5 -5.5 -0.2 -4.4 -6.1 7.6 6.9 -8.0 6.8 9.1 -8.5 -1.3 5.5 4.6 6.6 8.1 7.9 -9.3 9.6 4.6 0.9 -3.5 -4.3 -7.0 -1.2 7.0 7.1 -5.7 7.8 -2.3 4.3 0.2 -0.4 -6.6 7.6 -3.2 -5.4 -4.7 4.7 3.6 8.8 5.1 -3.1 -2.9 2.8 -4.3 -1.4 -1.8 -3.3 -5.6 1.8 8.3 -0.5 2.0 -3.9 -1.0 -8.6 8.0 -3.3 -2.5 -9.8 9.2 -0.8 -9.4 -0.5 1.6 1.5 3.4 -0.1 7.0 -6.2 -1.0 4.9 2.2 -8.7 -0.9 4.8 2.3 2.0 -3.2 -7.5 -4.0 9.9 -1.1 -2.9 8.7 3.6 7.4 7.8 10.0 -9.0 1.6 8.3 6.3 -5.8 -9.9 0.6 2.0 -3.8 -6.3 0.6 7.3 3.8 -7.1 9.5 2.2 1.3 -2.8 -9.1 7.1 -0.2 0.6 -6.5 1.1 -0.1 -3.6 4.0 -5.4 1.1 输出样例: -2.8
取两个坐标计算直线【副对角线】: y = -x + 11
#include<cstdio>
using namespace std;
const int N = 13;
double q[N][N], sum;
int main()
{
char op;
scanf("%c\n", &op);
for(int i = 0; i < 12; i++) //一个看图误区:需翻转90度看, 对角线应该为:y = x ---> 右上半部分 : y > x
for(int j = 0; j < 12; j++)
{
scanf("%lf", &q[i][j]);
if(j < -i + 11) //【下标】:倒头看:数组下标对应: y = x分界线(副对角线) , y = -x (正对角线)
sum += q[i][j];
}
if(op == 'S') printf("%.1lf", sum);
else printf("%.1lf", sum / 66.0); //个数 11 * (11 + 1) / 2
return 0;
}
747. 数组的左上半部分
输入一个二维数组 M[12][12],根据输入的要求,求出二维数组的左上半部分元素的平均值或元素的和。
左上半部分是指次对角线上方的部分,如下图所示,黄色部分为对角线,绿色部分为左上半部分:
输入格式 第一行输入一个大写字母,若为 S,则表示需要求出左上半部分的元素的和,若为 M,则表示需要求出左上半部分的元素的平均值。
接下来 12 行,每行包含 12 个用空格隔开的浮点数,表示这个二维数组,其中第 i+1 行的第 j+1 个数表示数组元素 M[i][j]。
输出格式 输出一个数,表示所求的平均数或和的值,保留一位小数。
数据范围 −100.0≤M[i][j]≤100.0 输入样例: M -0.4 -7.7 8.8 1.9 -9.1 -8.8 4.4 -8.8 0.5 -5.8 1.3 -8.0 -1.7 -4.6 -7.0 4.7 9.6 2.0 8.2 -6.4 2.2 2.3 7.3 -0.4 -8.1 4.0 -6.9 8.1 6.2 2.5 -0.2 -6.2 -1.5 9.4 -9.8 -3.5 -2.3 8.4 1.3 1.4 -7.7 1.3 -2.3 -0.1 -5.4 -7.6 2.5 -7.7 6.2 -1.5 -6.9 -3.9 -7.9 5.1 -8.8 9.0 -7.4 -3.9 -2.7 0.9 -6.8 0.8 -9.9 9.1 -3.7 -8.4 4.4 9.8 -6.3 -6.4 -3.7 2.8 -3.8 5.0 -4.6 2.0 4.0 9.2 -8.9 0.5 -3.9 6.5 -4.3 -9.9 -7.2 6.2 -1.2 4.1 -7.4 -4.6 4.7 -0.4 -2.2 -9.1 0.4 -5.8 9.1 -6.4 9.2 0.7 10.0 -5.7 -9.7 -4.4 4.7 4.7 4.9 2.1 -1.2 -6.2 -8.2 7.0 -5.3 4.9 5.5 7.2 3.4 3.2 -0.2 9.9 -6.9 -6.2 5.1 8.5 7.1 -0.8 -0.7 2.7 -6.0 4.2 -8.2 -9.8 -3.5 7.7 5.4 2.8 1.6 -1.0 6.1 7.7 -6.5 -8.3 -8.5 9.4 输出样例: -0.8
取两个坐标计算直线【副对角线】: y = -x + 11
#include<cstdio>
using namespace std;
const int N = 13;
double q[N][N], sum;
int main()
{
char op;
scanf("%c\n", &op);
for(int i = 0; i < 12; i++) //一个看图误区:需翻转90度看, 对角线应该为:y = x ---> 右上半部分 : y > x
for(int j = 0; j < 12; j++)
{
scanf("%lf", &q[i][j]);
if(j < -i + 11) //【下标】:倒头看:数组下标对应: y = x分界线(副对角线) , y = -x (正对角线)
sum += q[i][j];
}
if(op == 'S') printf("%.1lf", sum);
else printf("%.1lf", sum / 66.0); //个数 11 * (11 + 1) / 2
return 0;
}
748. 数组的右下半部分
输入一个二维数组 M[12][12],根据输入的要求,求出二维数组的右下半部分元素的平均值或元素的和。
右下半部分是指次对角线下方的部分,如下图所示,黄色部分为对角线,绿色部分为右下半部分:
输入格式 第一行输入一个大写字母,若为 S,则表示需要求出右下半部分的元素的和,若为 M,则表示需要求出右下半部分的元素的平均值。
接下来 12 行,每行包含 12 个用空格隔开的浮点数,表示这个二维数组,其中第 i+1 行的第 j+1 个数表示数组元素 M[i][j]。
输出格式 输出一个数,表示所求的平均数或和的值,保留一位小数。
数据范围 −100.0≤M[i][j]≤100.0 输入样例: S 9.7 -4.9 6.1 -6.1 -9.6 1.0 -3.2 0.6 3.2 -9.8 4.9 1.2 -2.8 -5.3 2.8 -1.9 -5.4 7.5 -2.0 5.7 2.3 5.3 -7.5 8.9 6.0 4.3 3.8 -6.7 8.1 -0.5 7.8 -2.2 -1.0 4.0 -4.9 -9.4 5.4 3.7 -6.5 -3.9 -3.3 4.1 -2.5 -4.7 8.2 1.4 1.8 4.7 2.4 9.0 -4.3 9.6 8.6 -6.1 -7.4 8.6 5.6 0.5 -0.4 5.2 -5.2 2.9 -5.6 4.0 -0.2 3.8 -4.1 -1.6 -3.8 -3.1 -1.1 3.3 -9.4 -1.4 0.6 6.5 -4.3 -8.3 6.1 2.9 -5.2 2.5 9.8 -7.7 -2.9 -3.6 7.9 -5.8 -4.7 8.2 -6.2 1.0 7.4 -1.0 -4.4 -4.5 0.1 9.5 4.9 1.5 0.8 -8.2 0.4 9.5 -0.8 -0.9 9.7 -2.1 0.1 -7.6 7.8 -6.9 5.5 1.4 4.0 7.8 1.0 -1.2 9.7 -1.9 -4.6 2.3 -5.5 8.2 -4.8 -3.7 5.4 0.2 -2.4 -0.8 7.4 0.0 -0.1 8.2 0.8 -3.5 -7.6 -0.5 5.6 8.4 -8.6 0.9 9.0 -7.5 输出样例: 53.0
#include<cstdio>
using namespace std;
const int N = 13;
double q[N][N], sum;
int main()
{
char op;
scanf("%c\n", &op);
for(int i = 0; i < 12; i++) //一个看图误区:需翻转90度看, 对角线应该为:y = x ---> 右上半部分 : y > x
for(int j = 0; j < 12; j++)
{
scanf("%lf", &q[i][j]);
if(j > -i + 11) //【下标】:倒头看:数组下标对应: y = x分界线(副对角线) , y = -x (正对角线)
sum += q[i][j];
}
if(op == 'S') printf("%.1lf", sum);
else printf("%.1lf", sum / 66.0); //个数 11 * (11 + 1) / 2
return 0;
}
749. 数组的上方区域
输入一个二维数组 M[12][12],根据输入的要求,求出二维数组的上方区域元素的平均值或元素的和。
数组的两条对角线将数组分为了上下左右四个部分,如下图所示,黄色部分为对角线,绿色部分为上方区域:
输入格式 第一行输入一个大写字母,若为 S,则表示需要求出上方区域的元素的和,若为 M,则表示需要求出上方区域的元素的平均值。
接下来 12 行,每行包含 12 个用空格隔开的浮点数,表示这个二维数组,其中第 i+1 行的第 j+1 个数表示数组元素 M[i][j]。
输出格式 输出一个数,表示所求的平均数或和的值,保留一位小数。
输出结果与标准答案据对误差不超过 0.1 即视为正确。
数据范围 −100.0≤M[i][j]≤100.0 输入样例: S -4.8 -8.0 -2.9 6.7 -7.0 2.6 6.5 1.7 1.9 5.6 -1.6 -6.3 -4.3 1.5 8.7 -0.3 5.4 -9.3 4.8 7.0 3.6 -8.3 -1.0 1.3 -9.9 9.7 -6.3 5.8 2.9 2.9 -7.7 4.9 -0.6 7.2 6.4 7.7 2.8 -5.8 -0.0 2.2 4.0 7.7 -3.0 -7.5 -3.5 9.7 -4.3 -8.6 -1.8 -0.1 5.4 0.6 9.9 -3.7 -1.1 0.8 -0.2 -0.0 9.9 4.5 3.0 -3.9 2.1 -9.7 5.5 9.4 -4.6 3.3 -9.6 5.1 -4.5 1.5 4.3 -5.4 -7.9 9.2 -7.7 -9.6 -1.5 -1.6 -7.2 2.0 -3.7 -0.7 8.0 2.8 -4.1 7.1 8.4 -5.6 3.9 -9.7 -1.1 3.0 -8.5 -3.3 1.7 5.1 0.1 9.2 4.5 9.7 7.2 8.6 8.7 1.1 6.7 0.3 -3.6 -7.1 -8.9 7.1 -5.9 1.6 -7.4 6.7 3.9 4.3 -2.4 -3.7 8.9 -6.2 5.0 -8.6 -1.3 -8.8 2.6 8.9 5.5 9.0 -2.2 -4.4 5.7 3.7 1.8 -2.1 -7.3 -7.9 4.7 6.0 3.3 -2.8 1.4 -6.9 输出样例: 21.7
上半部 = [右上部&&左上部] : 公共部分 j > i&& j + i < 11 两条对角线 y = x 与 y = -x + 11
#include<cstdio>
using namespace std;
const int N = 13;
double q[N][N], sum;
int main()
{
char op;
scanf("%c", &op);
for(int i= 0; i < 12 ; i++)
for(int j = 0 ;j < 12; j++)
{
scanf("%lf", &q[i][j]);
if(j > i && j < -i + 11) sum += q[i][j];
}
if(op == 'S') printf("%.1lf", sum);
else printf("%.1lf", sum / 30); // (10 + 2) * 5 / 2 == 30
return 0;
}
750. 数组的下方区域
输入一个二维数组 M[12][12],根据输入的要求,求出二维数组的下方区域元素的平均值或元素的和。
数组的两条对角线将数组分为了上下左右四个部分,如下图所示,黄色部分为对角线,绿色部分为下方区域:
输入格式 第一行输入一个大写字母,若为 S,则表示需要求出下方区域的元素的和,若为 M,则表示需要求出下方区域的元素的平均值。
接下来 12 行,每行包含 12 个用空格隔开的浮点数,表示这个二维数组,其中第 i+1 行的第 j+1 个数表示数组元素 M[i][j]。
输出格式 输出一个数,表示所求的平均数或和的值,保留一位小数。
数据范围 −100.0≤M[i][j]≤100.0 输入样例: S -6.0 0.7 -8.4 -5.7 -4.1 7.6 9.5 -9.7 4.1 0.6 -6.5 -4.9 6.6 4.9 -3.1 5.3 0.3 -4.5 3.9 -1.5 6.6 7.0 5.1 2.5 -8.5 1.8 -2.7 0.1 -4.9 -7.2 4.3 6.0 -1.4 2.7 -3.0 2.0 4.8 -7.0 -1.3 0.8 1.0 4.5 -1.1 -2.9 -3.9 -3.9 -8.9 5.8 -2.1 -9.6 5.1 0.2 1.0 -1.7 6.4 4.1 2.8 -6.9 2.4 9.3 -6.0 -9.1 -7.0 -7.0 7.8 5.1 6.9 -7.6 0.4 -7.2 5.5 6.0 -1.9 5.5 1.9 -8.5 -5.3 2.3 -9.3 2.0 -0.2 1.2 5.6 -1.8 8.2 2.3 3.5 1.4 4.0 -5.1 -6.9 -2.8 1.7 -7.0 7.8 1.8 -6.0 -4.1 -4.6 -9.4 -4.9 -4.1 4.2 6.3 -2.8 8.7 8.1 -0.9 8.8 -6.5 -4.3 6.1 -6.2 -3.9 -7.0 7.3 5.0 -0.9 -0.0 5.6 -2.4 1.4 8.5 -2.2 0.9 5.3 3.6 8.8 -8.1 3.0 -3.1 6.5 -3.8 -6.4 2.3 4.2 -9.8 -0.3 -9.9 -7.4 3.5 1.5 -0.2 7.0 输出样例: -11.9
#include<cstdio>
using namespace std;
const int N = 13;
double q[N][N], sum;
int main()
{
char op;
scanf("%c", &op);
for(int i= 0; i < 12 ; i++)
for(int j = 0 ;j < 12; j++)
{
scanf("%lf", &q[i][j]);
if(j < i && j > -i + 11) sum += q[i][j];
}
if(op == 'S') printf("%.1lf", sum);
else printf("%.1lf", sum / 30);
return 0;
}
751. 数组的左方区域
输入一个二维数组 M[12][12],根据输入的要求,求出二维数组的左方区域元素的平均值或元素的和。
数组的两条对角线将数组分为了上下左右四个部分,如下图所示,黄色部分为对角线,绿色部分为左方区域:
输入格式 第一行输入一个大写字母,若为 S,则表示需要求出左方区域的元素的和,若为 M,则表示需要求出左方区域的元素的平均值。
接下来 12 行,每行包含 12 个用空格隔开的浮点数,表示这个二维数组,其中第 i+1 行的第 j+1 个数表示数组元素 M[i][j]。
输出格式 输出一个数,表示所求的平均数或和的值,保留一位小数。
数据范围 −100.0≤M[i][j]≤100.0
mycode2022
#include<cstdio>
using namespace std;
const int N = 13;
double q[N][N], sum;
int main()
{
char op;
scanf("%c", &op);
for(int i= 0; i < 12 ; i++)
for(int j = 0 ;j < 12; j++)
{
scanf("%lf", &q[i][j]);
if(j < i && j < -i + 11) sum += q[i][j];
}
if(op == 'S') printf("%.1lf", sum);
else printf("%.1lf", sum / 30);
return 0;
}
哈夫曼距离
#include<cstdio>
#include<cmath>
int main(){
char a;
scanf("%c", &a);
double n[15][15];
for(int i = 0; i <12 ;i++){
for(int j = 0; j < 12; j++){
scanf("%lf", &n[i][j]);
}
}
double sum = 0;
int c = 0; //加计数器,不用自己算平均数分母
for(int i = 0; i < 12; i++){
for(int j = 0; j < 12; j++){
if((abs(5.5-i)+j) <= 4.5){ //麦哈顿距离 (比较不好想)
sum += n[i][j];
c++;
}
}
}
if(a == 'S') printf("%.1lf", sum);
else printf("%.1lf", sum / c);
return 0;
}
==法二:等效上半部矩阵转置【i,j互换位置】==
#include<bits/stdc++.h>
using namespace std;
char c;
double a[13][13],sum;
int main()
{
scanf("%c\n",&c);
for(int i = 0;i < 12;i++)
for(int j = 0;j < 12;j++)
{
scanf("%lf",&a[i][j]); //数组的左方区域:(i+j)<11 && i>j 【左上 - 上半 - 交集中的对角线】
if( i + j < 11 && i > j ) //不正确.. i < 11 && (j > i && j + i < 11) && j != i + 11
sum += a[i][j];
}
if(c == 'S') printf("%.1lf",sum);
else printf("%.1lf",sum/30); // 与上半部分相同个数
return 0;
}
曼尔顿距离用法【斜线适用 y = x或 -x + b】 ①(边界斜线或对角线交点):起点坐标(x1,y1) 与(i,j)
② |x1-x2| + |y1-y2| <= distance (等于看边界是否可取)
752. 数组的右方区域
输入一个二维数组 M[12][12],根据输入的要求,求出二维数组的右方区域元素的平均值或元素的和。
数组的两条对角线将数组分为了上下左右四个部分,如下图所示,黄色部分为对角线,绿色部分为右方区域:
输入格式 第一行输入一个大写字母,若为 S,则表示需要求出右方区域的元素的和,若为 M,则表示需要求出右方区域的元素的平均值。
接下来 12 行,每行包含 12 个用空格隔开的浮点数,表示这个二维数组,其中第 i+1 行的第 j+1 个数表示数组元素 M[i][j]。
输出格式 输出一个数,表示所求的平均数或和的值,保留一位小数。
数据范围 −100.0≤M[i][j]≤100.0 输入样例: S 2.4 7.8 9.4 -5.6 6.9 -4.9 4.8 0.8 3.6 1.7 -1.4 9.7 -6.8 -3.7 -2.0 -4.9 -4.5 -5.3 6.1 7.5 -4.3 5.9 -9.5 9.7 -6.5 -0.4 1.6 3.7 -4.4 -3.3 1.9 7.7 -1.4 4.5 7.4 -3.0 -1.2 0.4 9.8 9.8 -4.3 -1.3 -1.6 0.5 2.8 -4.0 8.5 3.9 0.2 -2.0 -6.4 -9.8 3.7 -2.0 1.7 -3.6 -3.4 2.4 -1.2 -3.9 -8.3 5.8 -1.0 -4.4 1.0 -2.4 2.8 -4.6 2.1 8.7 -6.8 -8.3 6.3 -6.8 -7.0 9.3 -7.7 -1.7 8.2 -6.5 -1.8 6.7 8.2 4.4 0.4 8.6 -1.2 8.6 -4.6 1.8 9.6 1.6 2.0 -1.0 3.9 -9.2 7.5 -3.1 6.2 -4.5 -3.0 2.5 -7.7 2.9 0.3 3.3 -2.7 3.4 -5.0 3.0 -0.0 4.3 9.5 -0.0 -9.9 -8.6 -0.9 -5.5 7.7 6.5 4.9 -9.6 -2.9 8.5 2.0 -9.9 -4.9 -1.5 -2.4 -7.6 1.7 8.5 -6.4 6.8 -3.7 -4.7 0.2 5.8 -5.4 0.6 7.0 -4.2 -7.5 -2.4 输出样例: 40.9
753. 平方矩阵 I
输入整数 N,输出一个 N 阶的回字形二维数组。
数组的最外层为 1,次外层为 2,以此类推。
输入格式 输入包含多行,每行包含一个整数 N。
当输入行为 N=0 时,表示输入结束,且该行无需作任何处理。
输出格式 对于每个输入整数 N,输出一个满足要求的 N 阶二维数组。
每个数组占 N 行,每行包含 N 个用空格隔开的整数。
每个数组输出完毕后,输出一个空行。
数据范围 0≤N≤100 输入样例: 1 2 3 4 5 0输出样例: 1
1 1 1 1
1 1 1 1 2 1 1 1 1
1 1 1 1 1 2 2 1 1 2 2 1 1 1 1 1
1 1 1 1 1 1 2 2 2 1 1 2 3 2 1 1 2 2 2 1 1 1 1 1 1
规律:四个方向到自身的最短距离
#include<iostream>
using namespace std;
int main()
{
int n;
while(scanf("%d", &n) && n)
{
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++) //复合简写:min(min(i + 1, j + 1), min(n - i, n - j))
{
int x = min(i + 1, n - i); //选取x
int y = min(j + 1, n - j); // 选取y
int z = min(x, y); //选取最短
printf("%d ", z);
}
puts("");
}
puts("");
}
return 0;
}
Chuckie写的很棒 曼哈顿距离法
①当n为奇数时, 找取中间点n / 2分别于行i列j的距离的最大值(max(abs(n / 2 - i), abs(n / 2 - j))),可以的如下图形(例如n == 5): 2 2 2 2 2 2 1 1 1 2 2 1 0 1 2 2 1 1 1 2 2 2 2 2 2 ②观察结果, 随着回形越深入,内外围回形相差为1, 因此想到 (n + 1) / 2 ③当n为偶数时,采用同样的方法, 这里我们就让中心点在图形的中间位置 (n - 1) / 2.0, 再求解其分别于行i列j的距离的最大值(max(abs((n - 1) / 2.0 - i), abs((n - 1) / 2.0 - j))) ④再考虑所得图形与实际结果相差值,这里我们依然设置(n + 1) / 2
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int n;
int a[100][100];
while (cin >> n, n)
{
for (int i = 0; i < n; i ++ )
for (int j = 0; j < n; j ++ )
{
if (n % 2) //n为奇数
{
a[i][j] = (n + 1) / 2 - max(abs(i - n / 2), abs(j - n / 2)); //中心点 (n / 2, n / 2 )
}
else //n为偶数
{
a[i][j] = n / 2 - max(min(abs(i - n / 2), abs(i - (n - 1) / 2)), min(abs(j - n / 2), abs(j - (n - 1) / 2)));
}
}
for (int i = 0; i < n; i ++ )
{
for (int j = 0; j < n; j ++ ) printf("%d ", a[i][j]);
puts("");
}
puts("");
}
return 0;
}
利用蛇形矩阵求解
①设置一个计数器统计方向改变次数 ②设置变量res表示回形当前圈数 ③其他部分与蛇形矩阵相同
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
const int N = 100 + 10;
int m[N][N];
int main(){
int n;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
while(cin >> n, n ){
memset(m, 0, sizeof m);
int d = 1, x = 0, y = 0;
int cnt = 0; // 表示改变方向次数
int res = 1; // 回形当前圈数
for (int i = 0; i < n * n; i ++){
int a = x + dx[d], b = y + dy[d];
m[x][y] = res;
if (a < 0 || a >= n || b < 0 || b >= n || m[a][b]){
d = (d + 1) % 4;
a = x + dx[d], b = y + dy[d];
cnt ++;
if (!(cnt % 4)) res ++;
}
x = a, y = b;
}
for (int i = 0; i < n; i ++){
for (int j = 0; j < n; j ++)
cout << m[i][j] << ' ';
cout << endl;
}
cout << endl;
}
return 0;
}
754. 平方矩阵 II
输入整数 N,输出一个 N 阶的二维数组。
数组的形式参照样例。
输入格式 输入包含多行,每行包含一个整数 N。
当输入行为 N=0 时,表示输入结束,且该行无需作任何处理。
输出格式 对于每个输入整数 N,输出一个满足要求的 N 阶二维数组。
每个数组占 N 行,每行包含 N 个用空格隔开的整数。
每个数组输出完毕后,输出一个空行。
数据范围 0≤N≤100 输入样例: 1 2 3 4 5 0输出样例: 1
1 2 2 1
1 2 3 2 1 2 3 2 1
1 2 3 4 2 1 2 3 3 2 1 2 4 3 2 1
1 2 3 4 5 2 1 2 3 4 3 2 1 2 3 4 3 2 1 2 5 4 3 2 1
法一:每次向右延伸和向下延伸看
规律:每轮从(i, i)开始往右和往下单调递增填
#include<cstdio>
using namespace std;
const int N = 105;
int n;
int q[N][N];
int main()
{
while(scanf("%d\n",&n), n)
{
for(int i = 0; i < n; i++)
{
for(int j = i,k = 1; j <= n; j++, k++) //每轮都需从k = 1开始 , j = i 开始(不要覆盖之前填的)
{
q[i][j] = k; //向右延伸
q[j][i] = k; //向下延伸
}
}
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
printf("%d ",q[i][j]);
}
puts("");
}
puts("");
}
return 0;
}
法二:正对角线(i, i)分界:左半向中间递增,右半递减填写每行 每行看:对角线前递增,对角线后递减 (不用数组,直接输出)
#include<cstdio>
using namespace std;
int n;
int main()
{
while(scanf("%d\n",&n), n)
{
for(int i = 1;i <= n; i++)
{
for(int j = i; j >= 1; j--) printf("%d ",j);
for(int j = i + 1; j <= n; j++) printf("%d ",j - i + 1); //【从1开始时】
puts("");
}
puts("");
}
return 0;
}
法三:下标与值规律
#include<cstdio>
using namespace std;
int n;
int main()
{
while(scanf("%d\n",&n), n)
{
for(int i = 1; i <= n; i++)
{
for(int j = 1; j < n; j++)
printf("%d ", abs(j - i) + 1); //【从1开始时,从0开始一样:|i-j|不变】
puts("");
}
puts("");
}
return 0;
}
其他法:还可以当作对称矩阵解题:上三角 = 下三角 对称 值相等
755. 平方矩阵 III
输入整数 N,输出一个 N 阶的二维数组 M。
这个 N 阶二维数组满足 M[i][j]=2i+j。
具体形式可参考样例。
输入格式 输入包含多行,每行包含一个整数 N。
当输入行为 N=0 时,表示输入结束,且该行无需作任何处理。
输出格式 对于每个输入整数 N,输出一个满足要求的 N 阶二维数组。
每个数组占 N 行,每行包含 N 个用空格隔开的整数。
每个数组输出完毕后,输出一个空行。
数据范围 0≤N≤15 输入样例: 1 2 3 4 5 0输出样例: 1
1 2 2 4
1 2 4 2 4 8 4 8 16
1 2 4 8 2 4 8 16 4 8 16 32 8 16 32 64
1 2 4 8 16 2 4 8 16 32 4 8 16 32 64 8 16 32 64 128 16 32 64 128 256
位运算:【 1 << (i + j)】
#include <cstdio>
using namespace std;
int main()
{
int n;
while (scanf("%d", &n), n)
{
for (int i = 0; i < n; i ++ )
{
for (int j = 0; j < n; j ++ )
{
printf("%d ", 1 << (i + j)); //用位运算表示2的幂运算 【超快】
}
puts("");
}
puts("");
}
return 0;
}
改造平方矩阵Ⅱ
#include<cstdio>
using namespace std;
const int N = 105;
int n;
int q[N][N];
int main()
{
while(scanf("%d\n",&n),n)
{
for(int i = 0;i < n;i++)
{
for(int j = i,k = 1 << (i + j);j < n; j++ , k <<= 1) //i,j从0开始:每轮从k = 2^(i + j)开始 ; k *= 2
{
q[i][j] = k; //向右延伸
q[j][i] = k; //向下延伸
}
}
for(int i = 0; i < n; i++)
{
for(int j = 0;j < n;j++)
{
printf("%d ",q[i][j]);
}
puts("");
}
puts("");
}
return 0;
}
下标与值规律 (按i行从1开始)-----> $2 ^ i * 2 ^ j == 2 ^ {i + j}$
#include<bits/stdc++.h>
using namespace std;
int n,t;
int main()
{
while(scanf("%d\n",&n),n)
{
for(int i = 0;i < n;i++)
{
for(int j = 0;j < n;j++)
{
t = 1;
for(int k = 0;k < i + j ; k ++)
{
t *= 2;
}
printf("%d ",t); // 2^(i+j)
}
printf("\n");
}
printf("\n");
}
return 0;
}
*756. 蛇形矩阵
输入两个整数 n 和 m,输出一个 n 行 m 列的矩阵,将数字 1 到 n×m 按照回字蛇形填充至矩阵中。
具体矩阵形式可参考样例。
输入格式 输入共一行,包含两个整数 n 和 m。
输出格式 输出满足要求的矩阵。
矩阵占 n 行,每行包含 m 个空格隔开的整数。
数据范围 1≤n,m≤100 输入样例: 3 3 输出样例: 1 2 3 8 9 4 7 6 5
向量枚举法
d与dx和dy初始值会影响输出结果!!!
#include<iostream>
using namespace std;
const int N = 110;
int n,m;
int q[N][N];
int main()
{
scanf("%d%d",&n,&m);
int dx[] = {-1,0,1,0} , dy[] = {0,1,0,-1};//固定风格写:-1开始-1结束
int x = 0,y = 0,d = 1;// d用于方向选择 1, 2, 3, 0 【上右下左】 d与dx和dy初始值会影响输出结果!!!
//DFS搜索 【注意方向向量必须先判断右到不能走再往下走,再判断左, 再判断上(即此题固定右下左上)】
for(int i = 1;i <= n * m;i++) //【用i赋值且遍历n*m格 】
{
q[x][y] = i; //赋值:每轮填i
int a = x + dx[d], b = y + dy[d];
if(a < 0 ||a >= n || b < 0 || b >= m || q[a][b]) //【出界或(a,b)已填过不能走,判断下一个方向】
{
d = (d+1) % 4;//判断下一个方向 【方向循环*妙*】
a = x + dx[d], b = y + dy[d];
}
x = a ,y = b; // 新起点
}
for(int i = 0;i < n;i++)
{
for(int j = 0;j < m;j++)
{
printf("%d ",q[i][j]);
}
puts("");
}
return 0;
}
/*
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110;
int n, m;
int a[N][N];
void print2D(int x, int y, int val, int dir)
{
if (val == n * m) return;
switch(dir){
case 0:
while (a[x][y + 1] == 0)
y ++, val ++, a[x][y] = val;
print2D(x, y, val, 1);
break;
case 1:
while (a[x + 1][y] == 0)
x ++, val ++, a[x][y] = val;
print2D(x, y, val, 2);
break;
case 2:
while (a[x][y - 1] == 0)
y --, val ++, a[x][y] = val;
print2D(x, y, val, 3);
break;
case 3:
while (a[x - 1][y] == 0)
x --, val ++, a[x][y] = val;
print2D(x, y, val, 0);
break;
}
}
int main()
{
cin >> n >> m;
for (int i = 0; i <= n + 1; i ++ )
a[i][0] = a[i][m + 1] = -1;
for (int j = 0; j <= m + 1; j ++ )
a[0][j] = a[n + 1][j] = -1;
print2D(1, 0, 0, 0);
for (int i = 1; i <= n; i ++ ){
for (int j = 1; j <= m; j ++ )
cout << a[i][j] << ' ';
cout << endl;
}
return 0;
}
*/
/*
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110;
int n, m, a[N][N];
bool check(int x, int y){
return x > 0 && x <= n && y > 0 && y <= m;
}
int main()
{
cin >> n >> m;
int x = 1, y = 0, val = 0;
while (val != n * m)
{
while (check(x, y + 1) && a[x][y + 1] == 0)
++ y, ++ val, a[x][y] = val;
while (check(x + 1, y) && a[x + 1][y] == 0)
++ x, ++ val, a[x][y] = val;
while (check(x, y - 1) && a[x][y - 1] == 0)
-- y, ++ val, a[x][y] = val;
while (check(x - 1, y) && a[x - 1][y] == 0)
-- x, ++ val, a[x][y] = val;
}
for (int i = 1; i <= n; i ++ )
{
for (int j = 1; j <= m; j ++ )
cout << a[i][j] << ' ';
cout << endl;
}
return 0;
}
*/