XDOJ矩阵类


螺旋方阵:

//分治
#include <stdio.h>
int a[100][100];

//该函数就是直接打印最外层的一圈数字,很好理解。
//number开始的数字,size代表圈的边长,begin代表位置
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;//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://blog.csdn.net/qq_39679772/article/details/103581240

马鞍点

标题	
马鞍点

类别
数组
	
时间限制	
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;         //标记变量,有1就是sign = 1
                if (j + 1 < n)        //现在不是最后一个元素
                {
                    if (a[i][j + 1] == 0 && count > max)     //下一个为0,需比较是否为最长
                    {
                        max = count;
                        location = j;
                        count = 0;              //因为1的连续结束了,所以count重赋值为0
                    }
                } else {     //现在是最后一个元素
                    if (count > max)     //需比较是否为最长
                    {
                        max = count;
                        location = j;
                        count = 0;              //因为1的连续结束了,所以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; //1:向右  2:向下  3:向左下  4:向右上
    while (count < n * n)
    {
        switch (state)
        {
        case 1:
            printf("%d ", matrix[i][j++]); //1:向右
            if (i == 0)
                state = 3;
            else if (i == n - 1)
                state = 4;
            break;
        case 2:
            printf("%d ", matrix[i++][j]); //2:向下
            if (j == 0)
                state = 4;
            else if (j == n - 1)
                state = 3;
            break;
        case 3:
            printf("%d ", matrix[i++][j--]); //3:向左下
            if (j == 0)
                state = 2;
            if (i == n - 1)
                state = 1;
            break;
        case 4:
            printf("%d ", matrix[i--][j++]); //4:向右上
            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
//给一个m*n的矩阵,其中有0-15的数字,看每个数字出现几次
//用一个count[20];数据来记录

# include <stdio.h>
int main()
{
    int count[20] = {0};
    //memset(count,0,sizeof(count));
    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;
}

  • 17
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值