1. 题目
示例输入
3 4 3 2
1 1 1
1 3 1
2 2 2
1 2 1
2 2 3
示例输出
1 1 1
1 2 1
1 3 1
2 2 5
2. 代码
需要注意行号和列号都是从1开始而不是从0开始的。
#include <iostream>
using namespace std;
typedef struct OLNode{
int row, col, num;
struct OLNode *right, *down;
}OLNode;
typedef struct{
OLNode *rhead[100], *chead[100];
int mu, nu, tu;
}CrossList;
// 初始化一个 m*n 的空十字链表
void init(CrossList *a, int m, int n){
a->mu = m;
a->nu = n;
a->tu = 0;
for(int i=1; i<=m; i++){
a->rhead[i] = NULL;
}
for(int i=1; i<=n; i++){
a->chead[i] = NULL;
}
}
// 分别加上两个矩阵,每个矩阵输入时占t行
void add(CrossList *a, int t){
OLNode *p, *q;
for(int i=1; i<=t; i++){
int r, c, n;
cin >> r >> c >> n;
// 判断这个位置之前是否有值
int flag = 0;
for(q=a->rhead[r]; q; q = q->right){
if(q->col == c){
q->num += n;
flag = 1;
break;
}
}
if(flag) continue;
// 将输入的一个非零元素装入一个结点
p = (OLNode*) malloc(sizeof(OLNode));
p->row = r;
p->col = c;
p->num = n;
// 如果这个位置没有值
// 首先行插入
// 如果该行没目前有非零元素(NULL) 或者 头结点的列值比应该插入的列值大,将其变成头结点
if(a->rhead[r] == NULL || a->rhead[r]->col > p->col){
p->right = a->rhead[r];
a->rhead[r] = p;
}
// 否则,找到p应该插入的位置并插入
else{
for(q = a->rhead[r]; (q->right) && q->right->col < c; q=q->right) ;
p->right = q->right;
q->right = p;
}
// 然后列插入
if(a->chead[c] == NULL || a->chead[c]->row > r){
p->down = a->chead[c];
a->chead[c] = p;
}
else{
for(q = a->chead[c]; (q->down) && q->down->row < r; q=q->down) ;
p->down = q->down;
q->down = p;
}
}
}
void output(CrossList *a){
OLNode *p;
for(int i=1; i<=a->mu; i++){
if(a->rhead[i] == NULL){
continue;
}
p = a->rhead[i];
while(p){
if(p->num == 0){
p = p->right;
continue;
}
cout << p->row << " " << p->col << " " << p->num << endl;
p = p->right;
}
}
}
int main(int argc, char** argv) {
CrossList *a = (CrossList*)malloc(sizeof(CrossList));
int m, n, t1, t2;
cin >> m >> n >> t1 >> t2;
init(a, m, n);
add(a, t1);
add(a, t2);
output(a);
return 0;
}