带状矩阵压缩初步
最近学习了带状矩阵,尝试压缩
带状矩阵就是所有的非零元素都集中在以主对角线为中心的带状区域中的矩阵,如下:

因此尝试简单的带状矩阵压缩
首先分析带状矩阵,设它的带宽(矩阵中的行最大的非零个数)为M,所以创建M*n大小的矩阵用于储存压缩后的矩阵
使得a[i][j] 可以直接访问A[i][j]的数值
令k = M/2,所以M 等于2*k+1,就是说k为主对角线一侧的最大元素个数
a[i][j]中,如果i <= k 那么a[i][j] = A[i][j]
i >k 时,a[i][j] = A[i][i-k+j]
做完了存储,接下来应该寻找相应位置的数据
讨论i>k的情况:(k,i,j已知)
假设k = k,当i= k+1时,A[i][j0] = a[i][1], a[i][j0+1] = a[i][2].(j0是该行第一个非零元素的索引,下同)
i= k+2时, A[i][j0] = a[i][2], a[i][j0+1] = a[i][3].
当i= k+m时, A[i][j0] = a[i][m]
最后,i = m(m>k)时,A[i][j0] =a[i][m-k], A[i][j] = a[i][j-(m-k)]=a[i][j-m+k] = a[i][j-i+k]
代码如下:
#include<stdio.h> int main(){ int n; scanf("%d", &n); int a[n][n]; int i, j, M; int count = 0; for(i = 0; i<n; i++){ for(j = 0; j<n; j++){ //输入 scanf("%d", &a[i][j]); } if(a[i][0]!= 0)// 得到最大元素个数 count = i; } M = 2*count +1; int tran[n][M];// 压缩矩阵 for(i = 0; i<n; i++){ if(i<=count) M = count+i+1; else M = count*2+1; for(j = 0; j<M; j++){ if(i<=count) tran[i][j] = a[i][j]; else{ tran[i][j] = a[i][i-count+j]; } } } while(1){//检测位置 scanf("%d%d", &i, &j); if(i<=count) printf("%d\n",tran[i][j]); else printf("%d\n",tran[i][j+count-i]); } return 0; }
浙公网安备 33010602011771号