螺旋方阵:
# include <stdio.h>
int a[ 100 ] [ 100 ] ;
void geta ( int number, int size, int begin)
{
int i, j, k;
if ( size == 0 )
return ;
if ( size == 1 )
{
a[ begin] [ begin] = number;
return ;
}
i = begin;
j = begin;
for ( k = 0 ; k < size - 1 ; k++ )
{
a[ i] [ j] = number;
number++ ;
i++ ;
}
for ( k = 0 ; k < size - 1 ; k++ )
{
a[ i] [ j] = number;
number++ ;
j++ ;
}
for ( k = 0 ; k < size - 1 ; k++ ) 下
{
a[ i] [ j] = number;
number++ ;
i-- ;
}
for ( k = 0 ; k < size - 1 ; k++ )
{
a[ i] [ j] = number;
number++ ;
j-- ;
}
geta ( number, size - 2 , begin + 1 ) ;
}
int main ( )
{
int n;
scanf ( "%d" , & n) ;
geta ( 1 , n, 0 ) ;
for ( int i = 0 ; i < n; i++ )
{
for ( int j = 0 ; j < n; j++ )
{
printf ( "%d " , a[ i] [ j] ) ;
}
printf ( "\n" ) ;
}
return 0 ;
}
矩阵相乘
矩阵相乘
输入2×3矩阵A和3×2矩阵B各元素值,计算矩阵A和矩阵B相乘的结果
输入说明:输入整形数组A和数组B,数组元素用空格分隔
输出说明:输出矩阵A*B的结果,矩阵元素之间用空格分隔,数组每行元素用换行分隔
输入样例:
1 2 3
4 5 6
1 2
3 4
5 6
输出样例
22 28
49 64
# include <stdio.h>
int main ( )
{
int A[ 2 ] [ 3 ] , B[ 3 ] [ 2 ] , res[ 2 ] [ 2 ] ;
int i, j, k;
for ( i = 0 ; i < 2 ; i ++ )
for ( j = 0 ; j < 3 ; j ++ )
scanf ( "%d" , & A[ i] [ j] ) ;
for ( i = 0 ; i < 3 ; i ++ )
for ( j = 0 ; j < 2 ; j ++ )
scanf ( "%d" , & B[ i] [ j] ) ;
for ( i = 0 ; i < 2 ; i ++ )
for ( j = 0 ; j < 2 ; j ++ )
res[ i] [ j] = 0 ;
for ( i = 0 ; i < 2 ; i ++ )
{
for ( j = 0 ; j < 2 ; j ++ )
{
for ( k = 0 ; k < 3 ; k ++ )
res[ i] [ j] = res[ i] [ j] + A[ i] [ k] * B[ k] [ j] ;
}
}
for ( i = 0 ; i < 2 ; i ++ )
{
for ( j = 0 ; j < 2 ; j ++ )
{
printf ( "%d " , res[ i] [ j] ) ;
}
printf ( "\n" ) ;
}
return 0 ;
}
矩阵转置
标题
图像旋转
类别
数组
时间限制
1S
内存限制
256Kb
问题描述
旋转是图像处理的基本操作,在这个问题中,你需要将一个图像顺时针旋转90度。
计算机中的图像可以用一个矩阵来表示,为了旋转一个图像,只需要将对应的矩阵旋转即可。例如,下面的矩阵(a)表示原始图像,矩阵(b)表示顺时针旋转90度后的图像。
输入说明
输入的第一行包含两个整数n和m,分别表示图像矩阵的行数和列数。1 ≤ n, m ≤ 100。
接下来n行,每行包含m个非负整数,表示输入的图像,整数之间用空格分隔。
输出说明
输出m行,每行n个整数,表示顺时针旋转90度之后的矩阵,元素之间用空格分隔。
输入样例
2 3
1 5 3
3 2 4
输出样例
3 1
2 5
4 3
# include <stdio.h>
int main ( )
{
int arr[ 101 ] [ 101 ] ;
int tmp[ 101 ] [ 101 ] = { 0 } ;
int ROW, COL, i, j;
scanf ( "%d %d" , & ROW, & COL) ;
for ( i = 0 ; i < ROW; i++ )
for ( j = 0 ; j < COL ; j++ ) scanf ( "%d" , & arr[ i] [ j] ) ;
int dst = ROW - 1 ;
for ( i = 0 ; i < ROW; i++ , dst-- )
for ( j = 0 ; j < COL ; j++ )
tmp[ j] [ dst] = arr[ i] [ j] ;
for ( i = 0 ; i < COL; i++ )
{
for ( j = 0 ; j < ROW; j++ )
printf ( "%d " , tmp[ i] [ j] ) ;
printf ( "\n" ) ;
}
return 0 ;
}
矩阵涂色
标题
画图
类别
数组
时间限制
1S
内存限制
256Kb
问题描述
在一个定义了直角坐标系的纸上,画一个(x1,y1)到(x2,y2)的矩形,指将横坐标范围从x1到x2,纵坐标范围从y1到y2之间的区域涂上颜色。
下图给出了一个画了两个矩形的例子。第一个矩形是(1,1) 到(4, 4),用绿色和紫色表示。第二个矩形是(2, 3)到(6, 5),用蓝色和紫色表示。
图中,一共有15个单位的面积被涂上颜色,其中紫色部分被涂了两次,但在计算面积时只计算一次。在实际的涂色过程中,所有的矩形 都涂成统一的颜色,图中显示不同颜色仅为说明方便。给出所有要画的矩形,请问总共有多少个单位的面积被涂上颜色。
输入说明
输入的第一行包含一个整数n,表示要画的矩形的个数,1<=n<=100
接下来n行,每行4个非负整数,分别表示要画的矩形的左下角的横坐标与纵坐标,以及右上角的横坐标与纵坐标。0<=横坐标、纵坐标<=100。
输出说明
输出一个整数,表示有多少个单位的面积被涂上颜色。
输入样例
2
1 1 4 4
2 3 6 5
输出样例
15
暴力模拟法:不考虑效率的话,将每一个矩形区域标记,然后最后遍历。
# include <stdio.h>
struct square {
int x1, y1, x2, y2;
} ;
int main ( )
{
int n, i, j, k, sum= 0 , a[ 101 ] [ 101 ] = { 0 } ;
struct square s[ 100 ] ;
scanf ( "%d" , & n) ;
for ( i= 0 ; i< n; i++ ) scanf ( "%d%d%d%d" , & s[ i] . x1, & s[ i] . y1, & s[ i] . x2, & s[ i] . y2) ;
for ( k= 0 ; k< n; k++ )
{
for ( i= s[ k] . x2; i> s[ k] . x1; i-- )
{
for ( j= s[ k] . y2; j> s[ k] . y1; j-- )
{
a[ i] [ j] = 1 ;
}
}
}
for ( i= 0 ; i< 101 ; i++ )
{
for ( j= 0 ; j< 101 ; j++ )
if ( a[ i] [ j] == 1 ) sum++ ;
}
printf ( "%d" , sum) ;
}
转自 https:
马鞍点
标题
马鞍点
类别
数组
时间限制
2S
内存限制
1000Kb
问题描述
若一个矩阵中的某元素在其所在行最小而在其所在列最大,则该元素为矩阵的一个马鞍点。
请写一个程序,找出给定矩阵的马鞍点。
输入说明
输入数据第一行只有两个整数m和n(0<m<100,0<n<100),分别表示矩阵的行数和列数;
接下来的m行、每行n个整数表示矩阵元素(矩阵中的元素互不相同),整数之间以空格间隔。
输出说明
在一行上输出马鞍点的行号、列号(行号和列号从0开始计数)及元素的值(用一个空格分隔),之后换行;
若不存在马鞍点,则输出一个字符串“no”后换行。
输入样例
4 3
11 13 121
407 72 88
23 58 1
134 30 62
输出样例
1 1 72
# include <stdio.h>
int main ( )
{
int a[ 101 ] [ 101 ] ;
int m, n;
scanf ( "%d %d" , & m, & n) ;
int i, j;
for ( i= 0 ; i< m; i++ )
for ( j= 0 ; j< n; j++ ) scanf ( "%d" , & a[ i] [ j] ) ;
int sign= 0 ;
int b[ 101 ] ;
for ( i= 0 ; i< m; i++ )
{
int min= a[ i] [ 0 ] ;
for ( j= 0 ; j< n; j++ )
{
if ( a[ i] [ j] < min)
{
min= a[ i] [ j] ;
}
}
b[ i] = min;
}
int c[ 101 ] ;
for ( i= 0 ; i< n; i++ )
{
int max = a[ 0 ] [ i] ;
for ( j= 0 ; j< m; j++ )
{
if ( a[ j] [ i] > max)
{
max= a[ j] [ i] ;
}
}
c[ i] = max;
}
for ( i= 0 ; i< m; i++ )
{
for ( j= 0 ; j< n; j++ )
if ( a[ i] [ j] == b[ i] && a[ i] [ j] == c[ j] )
{
printf ( "%d %d %d" , i, j, a[ i] [ j] ) ;
sign= 1 ;
}
}
if ( sign== 0 ) puts ( "no" ) ;
return 0 ;
}
0 -1矩阵
标题
0-1矩阵
类别
数组
时间限制
2S
内存限制
1000Kb
问题描述
查找一个只包含0和1的矩阵中每行最长的连续1序列。
输入说明
输入第一行为两个整数m和n(0<=m,n<=100)表示二维数组行数和列数,其后为m行数据,每行n个整数(0或1),输入数据中不会出现同一行有两个最长1序列的情况。
输出说明
找出每一行最长的连续1序列,输出其起始位置(从0开始计算)和结束位置(从0开始计算),如果这一行没有1则输出两个-1,然后换行。
输入样例
5 6
1 0 0 1 1 0
0 0 0 0 0 0
1 1 1 1 1 1
1 1 1 0 1 1
0 0 1 1 0 0
输出样例
3 4
-1 -1
0 5
0 2
2 3
# include <stdio.h>
int main ( ) {
int i, j, m, n, a[ 100 ] [ 100 ] ;
scanf ( "%d %d" , & m, & n) ;
for ( i = 0 ; i < m; i++ )
{
for ( j = 0 ; j < n; j++ )
scanf ( "%d" , & a[ i] [ j] ) ;
}
for ( i = 0 ; i < m; i++ )
{
int count = 0 , max = 0 , location = 0 , sign = 0 ;
for ( j = 0 ; j < n; j++ ) {
if ( a[ i] [ j] == 1 ) {
count++ ;
sign = 1 ;
if ( j + 1 < n)
{
if ( a[ i] [ j + 1 ] == 0 && count > max)
{
max = count;
location = j;
count = 0 ;
}
} else {
if ( count > max)
{
max = count;
location = j;
count = 0 ;
}
}
}
}
if ( sign) {
printf ( "%d %d\n" , location - max + 1 , location) ;
} else
puts ( "-1 -1" ) ;
}
return 0 ;
}
Z字形扫描
标题
Z字形扫描
类别
数组
时间限制
1S
内存限制
256Kb
问题描述
在图像编码的算法中,需要将一个给定的方形矩阵进行Z字形扫描(Zigzag Scan)。给定一个m×n的矩阵,Z字形扫描的过程如下图所示。
对于下面给出的4×4的矩阵:
1 5 3 9
3 7 5 6
9 4 6 4
7 3 1 3
对其进行Z字形扫描后得到长度为16的序列如下所示:
1 5 3 9 7 3 9 5 4 7 3 6 6 4 1 3
请实现一个Z字形扫描的程序,给定一个n×n的矩阵,输出对这个矩阵进行Z字形扫描的结果。
输入说明
数据的第一行为整数n(n<100),表示矩阵的行和列数;接下来的n行数据,每行分别为n个整数值(每个整数值都不超过1000),即矩阵的值
输出说明
在一行上输出Z字形扫描得到的整数序列,整数之间用空格分隔
输入样例
4
1 5 3 9
3 7 5 6
9 4 6 4
7 3 1 3
输出样例
1 5 3 9 7 3 9 5 4 7 3 6 6 4 1 3
# include <stdio.h>
int main ( )
{
int i, j, n, state, count = 0 , matrix[ 500 ] [ 500 ] ;
scanf ( "%d" , & n) ;
for ( i = 0 ; i < n; i++ )
for ( j = 0 ; j < n; j++ )
scanf ( "%d" , & matrix[ i] [ j] ) ;
i = 0 ;
j = 0 ;
state = 1 ;
while ( count < n * n)
{
switch ( state)
{
case 1 :
printf ( "%d " , matrix[ i] [ j++ ] ) ;
if ( i == 0 )
state = 3 ;
else if ( i == n - 1 )
state = 4 ;
break ;
case 2 :
printf ( "%d " , matrix[ i++ ] [ j] ) ;
if ( j == 0 )
state = 4 ;
else if ( j == n - 1 )
state = 3 ;
break ;
case 3 :
printf ( "%d " , matrix[ i++ ] [ j-- ] ) ;
if ( j == 0 )
state = 2 ;
if ( i == n - 1 )
state = 1 ;
break ;
case 4 :
printf ( "%d " , matrix[ i-- ] [ j++ ] ) ;
if ( i == 0 )
state = 1 ;
if ( j == n - 1 )
state = 2 ;
}
count++ ;
}
return 0 ;
}
相邻区域
标题
相邻区域
类别
数组
时间限制
1S
内存限制
256Kb
问题描述
一个n行m列的矩阵被划分成t个矩形区域,分别用数字1-t来标识,同一个区域内的元素都用同一个数字标识。如下图所示,一个6行8列的矩阵被分成8个矩形区域,分别用编号1-8标识。当两个小区域之间公用一条边时,称这两个区域相邻,例如下图中区域5的相邻区域有6个,分别为1,2,3,6,7,8,但4并不是它的相邻区域。请写一个程序找出区域k的所有相邻区域。
输入说明
输入第一行为四个整数n,m, t,k,整数之间用空格分隔。n表示矩阵行数(n<20),m表示矩阵列数(m<20),t表示矩阵被划分为t个矩形区域(0<t<50),k为其中某个区域的编号(1<=k<=t)。接下来是n行数据,每行m个整数,表示矩阵内各个元素所在的区域,整数之间用空格分隔。
输出说明
输出为一个整数,表示与k相邻的区域个数
输入样例
6 8 8 5
1 1 2 2 2 3 3 4
1 1 2 2 2 3 3 4
1 1 2 2 2 3 3 4
1 1 5 5 5 5 5 6
1 1 5 5 5 5 5 6
7 7 7 7 7 8 8 8
输出样例
6
# include <stdio.h>
int main ( void )
{
int array[ 20 ] [ 20 ] ;
int flag[ 50 ] = { 0 } ;
int n, m, t, k;
int i, j, count, x1, y1, x2, y2;
scanf ( "%d%d%d%d" , & n, & m, & t, & k) ;
for ( i = 0 ; i < n; i++ )
{
for ( j = 0 ; j < m; j++ )
{
scanf ( "%d" , & array[ i] [ j] ) ;
}
}
x1 = y1 = x2 = y2 = - 1 ;
for ( i = 0 ; i < n; i++ )
{
for ( j = 0 ; j < m; j++ )
{
if ( array[ i] [ j] == k)
{
if ( x1 == - 1 && x2 == - 1 )
{
x1 = i;
x2 = j;
}
if ( y1 < i)
{
y1 = i;
}
if ( y2 < j)
{
y2 = j;
}
}
}
}
count = 0 ;
for ( i = x1; i <= y1; i++ )
{
if ( x2 > 0 )
{
if ( flag[ array[ i] [ x2 - 1 ] ] == 0 )
{
count++ ;
flag[ array[ i] [ x2 - 1 ] ] = 1 ;
}
}
if ( y2 < m - 1 )
{
if ( flag[ array[ i] [ y2 + 1 ] ] == 0 )
{
count++ ;
flag[ array[ i] [ y2 + 1 ] ] = 1 ;
}
}
}
for ( j = x2; j <= y2; j++ )
{
if ( x1 > 0 )
{
if ( flag[ array[ x1 - 1 ] [ j] ] == 0 )
{
count++ ;
flag[ array[ x1 - 1 ] [ j] ] = 1 ;
}
}
if ( y1 < n - 1 )
{
if ( flag[ array[ y1 + 1 ] [ j] ] == 0 )
{
count++ ;
flag[ array[ y1 + 1 ] [ j] ] = 1 ;
}
}
}
printf ( "%d" , count) ;
return 0 ;
}
消除类游戏
问题描述
消除类游戏是深受大众欢迎的一种游戏,游戏在一个包含有n行m列的游戏棋盘上进行,棋盘的每一行每一列的方格上放着一个有颜色的棋子,当一行或一列上有连续三个或更多的相同颜色的棋子时,这些棋子都被消除。当有多处可以被消除时,这些地方的棋子将同时被消除。
现在给你一个n行m列的棋盘,棋盘中的每一个方格上有一个棋子,请给出经过一次消除后的棋盘。
请注意:一个棋子可能在某一行和某一列同时被消除。
输入格式
输入的第一行包含两个整数n, m,用空格分隔,分别表示棋盘的行数和列数。
接下来n行,每行m个整数,用空格分隔,分别表示每一个方格中的棋子的颜色。颜色使用1至9编号。
输出格式
输出n行,每行m个整数,相邻的整数之间使用一个空格分隔,表示经过一次消除后的棋盘。如果一个方格中的棋子被消除,则对应的方格输出0,否则输出棋子的颜色编号。
样例输入1
4 5
2 2 3 1 2
3 4 5 1 4
2 3 2 1 3
2 2 2 4 4
样例输出1
2 2 3 0 2
3 4 5 0 4
2 3 2 0 3
0 0 0 4 4
样例说明
棋盘中第4列的1和第4行的2可以被消除,其他的方格中的棋子均保留。
样例输入2
4 5
2 2 3 1 2
3 1 1 1 1
2 3 2 1 3
2 2 3 3 3
样例输出2
2 2 3 0 2
3 0 0 0 0
2 3 2 0 3
2 2 0 0 0
样例说明
棋盘中所有的1以及最后一行的3可以被同时消除,其他的方格中的棋子均保留。
评测用例规模与约定
所有的评测用例满足:1 ≤ n, m ≤ 30。
# include <stdio.h>
int main ( )
{
int m, n, i, j;
int a[ 100 ] [ 100 ] , b[ 100 ] [ 100 ] ;
scanf ( "%d %d" , & n, & m) ;
for ( i= 0 ; i< n; i++ )
{
for ( j= 0 ; j< m; j++ )
{
scanf ( "%d" , & a[ i] [ j] ) ;
b[ i] [ j] = a[ i] [ j] ;
}
}
for ( i= 0 ; i< n; i++ )
{
for ( j= 1 ; j< m- 1 ; j++ )
{
if ( a[ i] [ j] == a[ i] [ j- 1 ] && a[ i] [ j+ 1 ] == a[ i] [ j] )
{
b[ i] [ j- 1 ] = 0 ;
b[ i] [ j] = 0 ;
b[ i] [ j+ 1 ] = 0 ;
}
}
}
for ( j= 0 ; j< m; j++ )
{
for ( i= 1 ; i< n- 1 ; i++ )
{
if ( a[ i- 1 ] [ j] == a[ i] [ j] && a[ i+ 1 ] [ j] == a[ i] [ j] )
{
b[ i- 1 ] [ j] = 0 ;
b[ i] [ j] = 0 ;
b[ i+ 1 ] [ j] = 0 ;
}
}
}
for ( i= 0 ; i< n; i++ )
{
for ( j= 0 ; j< m; j++ )
printf ( "%d " , b[ i] [ j] ) ;
printf ( "\n" ) ;
}
}
75.灰度直方图
标题
灰度直方图
类别
数组
时间限制
2S
内存限制
1000Kb
问题描述
一幅m×n的灰度图像可以用一个二维矩阵表示,矩阵中的每个元素表示对应像素的灰度值。
灰度直方图表示图像中具有每种灰度级的象素的个数,反映图像中每种灰度出现的频率。
假设图像灰度为16级(灰度值从0-15),现给出一个矩阵表示的灰度图像,输出各级灰度的像素个数。
输入说明
输入数据第一行为两个整数m 和n分别表示图像的宽度和高度(0<=m,n<=256),其后是n行数据,每行m个整数,分别表示图像各个像素的灰度值。
输出说明
输出n行数据,每行数据由两个整数组成,分别表示灰度级和该灰度级像素个数,整数之间用空格分隔,灰度级输出顺序为从低到高,
如果某灰度级像素个数为0,则不输出该灰度级的统计结果。
输入样例
5 4
0 1 0 2 8
3 4 8 5 9
12 14 10 6 7
1 15 3 6 10
输出样例
0 2
1 2
2 1
3 2
4 1
5 1
6 2
7 1
8 2
9 1
10 2
12 1
14 1
15 1
# include <stdio.h>
int main ( )
{
int count[ 20 ] = { 0 } ;
int m, n;
scanf ( "%d %d" , & m, & n) ;
int i, number;
for ( i = 0 ; i < m * n; i ++ )
{
scanf ( "%d" , & number) ;
count[ number] ++ ;
}
for ( i = 0 ; i <= 15 ; i ++ )
{
if ( count[ i] != 0 )
printf ( "%d %d\n" , i, count[ i] ) ;
}
return 0 ;
}