题意:
模糊处理的图是将图中每个点的值改为距离本身曼哈顿距离d以内的点的平均值,先给你一个高为h,宽为w的模糊处理后的图让你还原为原图。
思路:
简单的高斯消元,只要对图中h*w个点找出曼哈顿距离d以内的点再列个方程,求高斯消元就行。
没注意看题习惯性的把第一个输入的w当做行数了,跪了快十几发,改了就A,QAQ。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=105;
const double eps=1e-8;
double a[maxn][maxn];
double rec[15][15];
double b[maxn];
void gass(int n, int m)
{
int i, j, row, col, equ=n*m, var=n*m;
for(row=1, col=1; row<=equ && col<=var; row++, col++)
{
int maxr=row;
for(i=row; i<=equ; i++)
{
if(fabs(a[i][col])>fabs(a[maxr][col]))
{
maxr=i;
}
}
if(fabs(a[maxr][col])<eps)
{
row--;
continue;
}
for(j=col; j<=var+1; j++)
{
swap(a[maxr][j], a[row][j]);
}
for(i=row+1; i<=equ; i++)
{
if(fabs(a[i][col])>eps)
{
double s=a[i][col]/a[row][col];
for(j=col; j<=var+1; j++)
{
a[i][j]-=a[row][j]*s;
}
}
}
}
for(i=equ; i>=1; i--)
{
double tmp=a[i][var+1];
for(j=i+1; j<=var; j++)
{
tmp-=a[i][j]*b[j];
}
b[i]=tmp/a[i][i];
}
return;
}
int main()
{
int n, m, d;
int first=1;
while(~scanf("%d%d%d", &n, &m, &d))
{
memset(a, 0, sizeof(a));
if(n+m+d==0)break;
int i, j;
for(i=1; i<=m; i++)
{
for(j=1; j<=n; j++)
{
scanf("%lf", &rec[i][j]);
}
}
int k;
for(k=1; k<=n*m; k++)
{
int x=(k-1)/n+1, y=k%n;
if(y==0)y=n;
double num=0;
for(i=1; i<=m; i++)
{
for(j=1; j<=n; j++)
{
if(abs(i-x)+abs(j-y)<=d)
{
a[k][(i-1)*n+j]=1;
num+=1;
}
}
}
a[k][n*m+1]=num*rec[x][y];
}
gass(n,m);
if(first)first=0;
else printf("\n");
for(i=1; i<=n*m; i++)
{
printf("%8.2lf", b[i]);
if(i%n==0)printf("\n");
}
}
return 0;
}