某农业大学数据结构A-第7周作业

1.稀疏矩阵快速转置

【问题描述】

        稀疏矩阵的存储不宜用二维数组存储每个元素,那样的话会浪费很多的存储空间。所以可以使用一个一维数组存储其中的非零元素。这个一维数组的元素类型是一个三元组,由非零元素在该稀疏矩阵中的位置(行号和列号对)以及该元组的值构成。而矩阵转置就是将矩阵行和列上的元素对换。

        请你实现一个快速的对稀疏矩阵进行转置的算法。

(注意:我看到部分同学提交的代码是简单转置+排序,请务必修改为快速转置算法哦。)

【输入形式】

        输入的第一行是两个整数r和c(r<200, c<200, r*c <= 12500),分别表示一个包含很多0的稀疏矩阵的行数和列数。接下来有r行,每行有c个整数,用空格隔开,表示这个稀疏矩阵的各个元素。

【输出形式】

        输出为读入的稀疏矩阵的转置矩阵。输出共有c行,每行有r个整数,每个整数后输出一个空格。请注意行尾输出换行。

【样例输入】

6 7
0 12 9 0 0 0 0
0 0 0 0 0 0 0
-3 0 0 0 0 14 0
0 0 24 0 0 0 0
0 18 0 0 0 0 0
15 0 0 -7 0 0 0

【样例输出】

0 0 -3 0 0 15
12 0 0 0 18 0
9 0 0 24 0 0
0 0 0 0 0 -7
0 0 0 0 0 0
0 0 14 0 0 0
0 0 0 0 0 0 

【提示】

第二组测试数据行列较大,注意空间开大一点哦。

#include<iostream>
#define MAXSIZE 10000
using namespace std;

typedef struct{
    int row,col;
    int e;
}Triple;

typedef struct{
    Triple data[MAXSIZE+1];
    int m,n,len;
}Matrix;

void Create(Matrix *a)
{
    int i,j,k;
    a->len=0;
    cin>>a->m>>a->n;
    for(i=1;i<=a->m;i++)
	{
        for(j=1;j<=a->n;j++)
		{
            cin>>k;
            if(k!=0)
			{
                a->len++;
                a->data[a->len].row=i;
                a->data[a->len].col=j;
                a->data[a->len].e=k;
            }
        }
    }
}
void Tranpose(Matrix a,Matrix *b)
{
    int i,j,k;
    b->len=a.len;
    b->m=a.n;
    b->n=a.m;
    int pos[MAXSIZE],num[MAXSIZE];
    //计算当中的非零元素个数 
    for(i=1;i<=a.n;i++)
        num[i]=0;
    for(i=1;i<=a.len;i++)
        num[a.data[i].col]++;
    //计算非零元素的位置 
    pos[1]=1;
    for(j=2;j<=a.n;j++)
        pos[j]=pos[j-1]+num[j-1];
    //快速一次定位 
    for(i=1;i<=a.len;i++)
	{
        j=a.data[i].col;
        k=pos[j];
        b->data[k].col=a.data[i].row;
        b->data[k].row=a.data[i].col;
        b->data[k].e=a.data[i].e;
        pos[j]++;
    }
}
void Print(Matrix b)
{
    int i,j,k=1;
    for(i=1;i<=b.m;i++)
	{
        for(j=1;j<=b.n;j++)
		{
            if(i==b.data[k].row&&j==b.data[k].col)
			{
                cout<<b.data[k].e<<" ";
                k++;
            }
            else
			{
                cout<<0<<" ";
            }
        }
        cout<<endl;
    }
}

int main()
{
    Matrix a,b;
    Create(&a);
    Tranpose(a,&b);
    Print(b);
    return 0;
}

2.三元组的矩阵加法

【问题描述】

以三元组表存储的稀疏矩阵A、B非零元个数分别为m和n。试编写程序,完成A+B。

【输入形式】

第一排为分别为A、B元素的个数,以下各排分别输入对应的三元组,头m组为A中的元素,接下来为B的元素,同一个矩阵的元素按照行递增排列,第一行规定为1,同一行的元素按照列递增排列,第一列规定为1

【输出形式】

为相应的三元组,以回车分开,如果结果全部为0,则输出 -1 -1 -1

【样例输入】

2 1

1 2 3

1 3 4

1 3 3

【样例输出】

1 2 3

1 3 7

#include<stdio.h>
#include<stdlib.h>
#define  MAXSIZE 1000

typedef struct 
{
    int e;
    int row,col;
}Triple;
 
typedef struct 
{
    Triple data[MAXSIZE+1];
    int m,n,len;
}Matrix;

Matrix t1;
Matrix t2;

void InputMatrix(Matrix *t1,Matrix *t2)
{
    scanf("%d%d",&t1->len,&t2->len);
    int i;
    for(i=1;i<=t1->len;i++)
    {
        scanf("%d%d%d",&t1->data[i].row,&t1->data[i].col,&t1->data[i].e);
    }
   for(i=1;i<=t2->len;i++)
    {
        scanf("%d%d%d",&t2->data[i].row,&t2->data[i].col,&t2->data[i].e);
    }
}
 
void AddMastrix(Matrix a,Matrix b,Matrix *c)
{
    int i=1,j=1,k=1;
    c->m=a.m;
	c->n=a.n;
    while (i<=a.len && j<= b.len)
    {
        if (a.data[i].row < b.data[j].row)
        {
            c->data[k] = a.data[i];
            i++;
            k++;
        }
      else  if (a.data[i].row > b.data[j].row)
        {
            c->data[k] = b.data[j];
            j++;
            k++;
        }
      else if (a.data[i].row == b.data[j].row)
        {
            if (a.data[i].col < b.data[j].col)
            {
                c->data[k] = a.data[i];
                i++;
                k++;
            }
            else  if (a.data[i].col > b.data[j].col)
            {
                c->data[k] = b.data[j];
                j++;
                k++;
            }
            else if (a.data[i].col == b.data[j].col)
                {
                if (a.data[i].e + b.data[j].e != 0)
                {
                    c->data[k].row=a.data[i].row;
                    c->data[k].col=a.data[i].col;
                    c->data[k].e=a.data[i].e+b.data[j].e;
                    k++;
                }
                j++;
                i++;
                }
        }
    }
    while (i<=a.len)
    {
        c->data[k]=a.data[i];
        k++;
        i++;
    }
    while (j<= b.len)
    {
        c->data[k]=b.data[j];
        k++;
        j++;
    }
    c->len=k-1;
}

void Output(Matrix t)
{
    int i,flag=0;
    for(i=1;i<=t.len;i++)
    {
    	flag++;
		printf("%d %d %d\n",t.data[i].row,t.data[i].col,t.data[i].e);
    }
    if(flag==0)
    {
    	printf("-1 -1 -1");
	}
}
 
int main()
{
    Matrix a,b,c;
    InputMatrix(&a,&b);
    AddMastrix(a,b,&c);
    Output(c);
    return 0;
}
3.九宫格数独游戏

【问题描述】
 数独是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9X9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫内的数字均含1-9,不重复。要求使用合适的数据结构和算法,求解出所有剩余空格的数字。


【输入形式】
 输入为9X9的二维数组,每个数字均为0-9之间的数字,其中0表示该位置的数字为未知。

【输出形式】
 输出为9X9的二维数组,每个数字均为1-9之间的数字,满足

【样例输入】

0 0 3 5 0 0 0 0 2
0 0 8 6 0 0 0 0 0
0 7 0 0 0 0 1 0 0
0 1 0 0 0 0 6 0 0
0 5 0 0 1 0 0 7 0
0 0 6 9 0 0 0 3 0
0 0 9 0 0 0 0 5 0
0 0 0 0 0 9 7 0 0
6 0 0 0 0 8 9 0 0
 

【样例输出】

1 6 3 5 4 7 8 9 2
5 9 8 6 2 1 3 4 7
2 7 4 8 9 3 1 6 5
3 1 7 4 8 5 6 2 9
9 5 2 3 1 6 4 7 8
8 4 6 9 7 2 5 3 1
7 8 9 1 6 4 2 5 3
4 3 1 2 5 9 7 8 6
6 2 5 7 3 8 9 1 4

【评分标准】
深搜或者其他算法均可

#include<bits/stdc++.h>
using namespace std;
const int N = 10;
int a[N][N];
//	行				列				九宫格 的 1 - 9是否存在 
bool vis1[10][10], vis2[10][10], vis3[10][10];
 
//深搜 
void dfs(int i, int j) {
	//搜完 
	if(i > 9) {	
	//打印 
		for(int i = 1; i <= 9; i++) {
			for(int j = 1; j <= 9; j++) {
				cout << a[i][j] << " ";
			}
			cout << endl;
		}
		return;
	}
	//a[i][j] 是否确定 
	if(!a[i][j])
	for(int k = 1, pos = ((i - 1) / 3) * 3 + (j - 1) / 3 + 1; k <= 9; k++) {
		//符合要求赋值并继续搜索 
		if(!vis1[i][k] && !vis2[j][k] && !vis3[pos][k]) {
			a[i][j] = k;
			vis1[i][k] = vis2[j][k] = vis3[pos][k] = 1; 
			//换行 
			if(j <= 8) dfs(i, j + 1);
			else dfs(i + 1, 1);
			//回溯 
			a[i][j] = 0; 
			vis1[i][k] = vis2[j][k] = vis3[pos][k] = 0; 
		}
	}else {
			if(j <= 8) dfs(i, j + 1);
			else dfs(i + 1, 1);
	}
}
 
int main() {
	for(int i = 1; i <= 9; i++)
	for(int j = 1; j <= 9; j++){
		cin >> a[i][j];
		//标记元素是否存在 
		vis1[i][a[i][j]] = vis2[j][a[i][j]] = vis3[((i - 1) / 3) * 3 + (j - 1) / 3 + 1][a[i][j]] = 1;
	}
	dfs(1, 1);
}
4.数组主元素

【问题描述】这是一道2013年考研真题,已知一个整数序列A长度为N,其中若存在a,且a的个数大于N/2,则称a为A的主元素

例如:3 5 5 3 5 7 5 5,其主元素为5

又如:3 5 5 3 5 1 5 7,其中没有主元素。

假设元素保存在一个一维数组中,请设计一个尽可能高效的算法,找出主元素。若存在主元素则输出该元素否则输出

要求时间复杂度为O(N),请注意穷举法时间复杂度是O(N^2),排序再遍历查找的时间复杂度是O(N*logN+N)

【输入形式】

一个整数数组,以0作为结束输入

【输出形式】

主元素,若没有则输出-1

【样例输入】

3 5 5 3 5 7 5 5 0

【样例输出】

5

【样例说明】长度为8,共有5个‘5’

#include<stdio.h>
#define MAX 10000
int a[MAX],b[MAX],len;

int main()
{
	int i=0,j=0;
	int max,flag=-1;
	while(1)
	{
		scanf("%d",&a[i]);
		if(max<a[i]) max=a[i];
		if(a[i]==0) break;
		i++;
	}
	len=i;
	for(j=1;j<=max;j++)
	{
		b[j]=0;
	}
	for(j=0;j<=max;j++)
	{
		b[a[j]]++;
	}
	for(j=1;j<=max;j++)
	{
		if(b[j]>(len/2))
		{
			printf("%d ",j);
			flag=0;
		}
	}
	if(flag==-1)
	printf("-1");
 } 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值