1. | 稀疏矩阵快速转置 【问题描述】 稀疏矩阵的存储不宜用二维数组存储每个元素,那样的话会浪费很多的存储空间。所以可以使用一个一维数组存储其中的非零元素。这个一维数组的元素类型是一个三元组,由非零元素在该稀疏矩阵中的位置(行号和列号对)以及该元组的值构成。而矩阵转置就是将矩阵行和列上的元素对换。 请你实现一个快速的对稀疏矩阵进行转置的算法。 (注意:我看到部分同学提交的代码是简单转置+排序,请务必修改为快速转置算法哦。) 【输入形式】 输入的第一行是两个整数r和c(r<200, c<200, r*c <= 12500),分别表示一个包含很多0的稀疏矩阵的行数和列数。接下来有r行,每行有c个整数,用空格隔开,表示这个稀疏矩阵的各个元素。 【输出形式】 输出为读入的稀疏矩阵的转置矩阵。输出共有c行,每行有r个整数,每个整数后输出一个空格。请注意行尾输出换行。 【样例输入】 6 7 【样例输出】 0 0 -3 0 0 15 【提示】 第二组测试数据行列较大,注意空间开大一点哦。 |
---|
#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. | 九宫格数独游戏 【问题描述】
【样例输出】 |
---|
#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");
}