HDU3359(高斯消元浮点数版)

Kind of a Blur

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2568 Accepted Submission(s): 694

Problem Description
Image blurring occurs when the object being captured is out of the camera’s focus. The top two figures on the right are an example of an image and its blurred version. Restoring the original image given only the blurred version is one of the most interesting topics in image processing. This process is called deblurring, which will be your task for this problem.
In this problem, all images are in grey-scale (no colours). Images are represented as a 2 dimensional matrix of real numbers, where each cell corresponds to the brightness of the corresponding pixel. Although not mathematically accurate, one way to describe a blurred image is through averaging all the pixels that are within (less than or equal to) a certain Manhattan distance?from each pixel (including the pixel itself ). Here’s an example of how to calculate the blurring of a 3x3 image with a blurring distance of 1:

Given the blurred version of an image, we are interested in reconstructing the original version assuming that the image was blurred as explained above.

Input
Input consists of several test cases. Each case is specified on H + 1 lines. The first line specifies three non negative integers specifying the width W, the height H of the blurred image and the blurring distance D respectively where (1<= W,H <= 10) and (D <= min(W/2,H/2)). The remaining H lines specify the gray-level of each pixel in the blurred image. Each line specifies W non-negative real numbers given up to the 2nd decimal place. The value of all the given real numbers will be less than 100.
Zero or more lines (made entirely of white spaces) may appear between cases. The last line of the input file consists of three zeros.

Output
For each test case, print a W * H matrix of real numbers specifying the deblurred version of the image. Each element in the matrix should be approximated to 2 decimal places and right justified in a field of width 8. Separate the output of each two consecutive test cases by an empty line. Do not print an empty line after the last test case. It is guaranteed that there is exactly one unique solution for every test case.

Sample Input
2 2 1
1 1
1 1

3 3 1
19 14 20
12 15 18
13 14 16

4 4 2
14 15 14 15
14 15 14 15
14 15 14 15
14 15 14 15

0 0 0

Sample Output
1.00 1.00
1.00 1.00

2.00   30.00   17.00

25.00 7.00 13.00
14.00 0.00 35.00

1.00   27.00    2.00   28.00

21.00 12.00 17.00 8.00
21.00 12.00 17.00 8.00
1.00 27.00 2.00 28.00
Hint

The Manhattan Distance (sometimes called the Taxicab distance) between
two points is the sum of the (absolute) difference of their coordinates.
The grid on the lower right illustrates the Manhattan distances from the grayed cell.

解题思路:n 个方程, n 个未知数,而且题目说一定有解,直接利用高斯消元弄一下就行,这是我第一次写高斯消元的题目,代码有点丑。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 500;
double eps = 1e-9;
int W, H;//宽和高
int D;
double S[maxn][maxn];//增广矩阵
double B[maxn][maxn];//题目所给矩阵
void Gauss(double A[maxn][maxn], int num)//res为增广矩阵,num为变量个数
{
    //使用列主消元法
    for(int i = 1; i <= num; i++)//枚举每一行
    {
        int r = i;
        for(int j = i + 1; j <= num; j++)//找出系数最大的一行
        {
            if(fabs(A[r][i]) - fabs(A[j][i]) < eps) r = j;
        }
        if(r != i)//交换第r, i行
        {
            for(int j = i; j <= num + 1; j++)
            {
                swap(A[i][j], A[r][j]);
            }
        }
        for(int j = i + 1; j <= num; j++)//用第i行乘以每一个数,然后加到第j行,从而消去未知数
        {
            double term = A[j][i] / A[i][i];
            for(int k = i; k <= num + 1; k++)
            {
                A[j][k] -= term * A[i][k];
            }
        }
    }
    //增广矩阵已经化成下三角矩阵,然后迭代求解就行
    for(int i = num; i >= 1; i--)
    {
        for(int j = i + 1; j <= num; j++)
        {
            A[i][num + 1] -= A[i][j] * A[j][j];
        }
        A[i][i] = A[i][num + 1] / A[i][i];
    }
}
int main()
{
    bool flag = true;
    while(~scanf("%d%d%d", &W, &H, &D) && H)
    {
        memset(S, 0, sizeof(S));
        for(int i = 1; i <= H; i++)
        {
            for(int j = 1; j <= W; j++)
            {
                scanf("%lf", &B[i][j]);
            }
        }
        for(int i = 1; i <= H; i++)
        {
            for(int j = 1; j <= W; j++)
            {
                int ans = 0;
                for(int k = 1; k <= H; k++)
                {
                    for(int p = 1; p <= W; p++)
                    {
                        if(abs(k - i) + abs(p - j) <= D)
                        {
                            ans++;
                            S[(i - 1) * W + j][(k - 1) * W + p] = 1;
                        }
                    }
                }
                S[(i - 1) * W + j][H * W + 1] = ans * B[i][j];
            }
        }//构造增广矩阵
        Gauss(S, H * W);
        if(flag)
        {
            flag = false;

        }
        else
        {
            printf("\n");
        }
        for(int i = 1; i <= H; i++)
        {
            for(int j = 1; j <= W; j++)
            {
                printf("%8.2lf", S[(i - 1) * W + j][(i - 1) * W + j]);
            }
            printf("\n");
        }
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值