描述
在图像处理的技术中,经常会用到算子与图像进行卷积运算,从而达到平滑图像或是查找边界的效果。
假设原图为H × W的矩阵A,算子矩阵为D × D的矩阵Op,则处理后的矩阵B大小为(H-D+1) × (W-D+1)。其中:
B[i][j] = ∑(A[i-1+dx][j-1+dy]*Op[dx][dy]) | (dx = 1 .. D, dy = 1 .. D), 1 ≤ i ≤ H-D+1, 1 ≤ j ≤ W-D+1
给定矩阵A和B,以及算子矩阵的边长D。你能求出算子矩阵中每个元素的值吗?
输入
第1行:3个整数,H, W, D,分别表示原图的高度和宽度,以及算子矩阵的大小。5≤H,W≤60,1≤D≤5,D一定是奇数。
第2..H+1行:每行W个整数,第i+1行第j列表示A[i][j],0≤A[i][j]≤255
接下来H-D+1行:每行W-D+1个整数,表示B[i][j],B[i][j]在int范围内,可能为负数。
输入保证有唯一解,并且解矩阵的每个元素都是整数。
输出
第1..D行:每行D个整数,第i行第j列表示Op[i][j]。
5 5 3 1 6 13 10 3 13 1 5 6 15 8 2 15 0 12 19 19 17 18 18 9 18 19 5 17 22 15 6 35 -36 51 -20 3 -32
0 1 0 1 -4 1 0
Op[1][1]、Op[2][1]、……Op[D][1]、Op[2][1]、Op[2][2]、……Op[D][D] 这D*D个未知变量
i*j个等式 求位置变量的值
高斯消元
但是很奇怪的是。。。数组为什么要开的那么大才能过 根据这个题目的数据范围 我觉的没有必要搞这么大的啊。。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <queue>
#define MEM(a,x) memset(a,x,sizeof a)
#define eps 1e-9
#define MOD 10009
#define MAXN 10010
#define MAXM 100010
#define INF 99999999
#define ll __int64
#define bug cout<<"here"<<endl
#define fread freopen("ceshi.txt","r",stdin)
#define fwrite freopen("out.txt","w",stdout)
using namespace std;
int A[110][110],B[110][110];
double a[5000][5000],x[5000];
int equ,var;
int Gauss()
{
int i,j,k,col,max_r;
for(k=0,col=0;k<equ&&col<var;k++,col++)
{
max_r=k;
for(i=k+1;i<equ;i++)
if(fabs(a[i][col])>fabs(a[max_r][col]))
max_r=i;
if(fabs(a[max_r][col])<eps) return 0;
if(k!=max_r)
{
for(j=col;j<var;j++)
{
swap(a[k][j],a[max_r][j]);
}
swap(x[k],x[max_r]);
}
x[k]/=a[k][col];
for(j=col+1;j<var;j++)
a[k][j]/=a[k][col];
a[k][col]=1;
for(i=0;i<equ;i++)
if(i!=k)
{
x[i]-=x[k]*a[i][col];
for(j=col+1;j<var;j++)
a[i][j]-=a[k][j]*a[i][col];
a[i][col]=0;
}
}
return 1;
}
int main()
{
// fread;
int h,w,d;
while(scanf("%d%d%d",&h,&w,&d)!=EOF)
{
for(int i=0;i<h;i++)
for(int j=0;j<w;j++)
scanf("%d",&A[i][j]);
for(int i=0;i<h-d+1;i++)
for(int j=0;j<w-d+1;j++)
scanf("%d",&B[i][j]);
int num=0;
for(int i=0;i<h-d+1;i++)
for(int j=0;j<w-d+1;j++)
{
for(int k=0;k<d;k++)
for(int l=0;l<d;l++)
{
a[num][k*d+l]=A[i+k][j+l];
}
x[num]=B[i][j];
num++;
}
equ=num;//等式个数
var=d*d;//变量个数
Gauss();
for(int i=0;i<d*d;i++)
{
if(i%d!=0) printf(" ");
if(x[i]>-1e-6) printf("%.0f",x[i]+1e-6);
else printf("%.0f",x[i]-1e-6);
if(i%d==d-1) puts("");
}
}
return 0;
}