HDU_3359 Kind of a Blur 【浮点型高斯消元+BFS】

一、题目

  Kind of a Blur

二、分析

  题目读起来挺费劲的。

  主要就是要求一个矩阵,其中每个点及其于这个的曼哈顿距离小于D的点的值总和的平均值就是新生成的矩阵。

  给定新生成的矩阵,求初始矩阵。

  相当于就是一个点的值与多个点的值相关联,那么列一个(WH)列,(WH)个未知数的方程组,然后解方程就可以了,由于值是浮点型,那么就是浮点型的高斯消元。

三、AC代码

#include <bits/stdc++.h>

using namespace std;
#define ll long long
#define Min(a,b) ((a)>(b)?(b):(a))
#define Max(a,b) ((a)>(b)?(a):(b))

const int maxn = 2e2 + 20;
const double eps = 1e-7;
int W, H, D;
double M[20][20];

class GaussMatrix
{
public:
    double a[maxn][maxn];
    int equ, val;   //行数、列数
    void swapRow(int rowOne, int rowTwo)
    {
        for(int i = 1; i <= val; ++i)
        {
            swap(a[rowOne][i], a[rowTwo][i]);
        }
    }
    void swapCol(int colOne, int colTwo)
    {
        for(int i = 1; i <= equ; ++i)
        {
            swap(a[i][colOne], a[i][colTwo]);
        }
    }
    bool same(double x, double y)
    {
        return fabs(x - y) < eps;
    }
    int guass()
    {
        int k, col;
        for(k = 1, col = 1; k <= equ && col < val; k++, col++)
        {
            //找到[k, equ]行中,col列值最大的行
            int maxRow = k;
            for(int i = k + 1; i <= equ; i++)
            {
                if(fabs(a[i][col]) > fabs(a[maxRow][col]))
                {
                    maxRow = i;
                }
            }
            //如果col列都为0,直接处理下一列
            if(same(a[maxRow][col], 0))
            {
                --k;
                continue;
            }
            if(maxRow != k)
                swapRow(k, maxRow);
            //约掉最上面这行约数,是当前行第col列第一个数系数为1
            for(int i = col + 1; i <= val; i++)
            {
                a[k][i] /= a[k][col];
            }
            a[k][col] = 1.0;
            //消元
            //1*x + b*y + c*z = d1
            //a2*x + b2*y + c2*z = d2
            //a3*x + b3*y + c3*z = d3
            for(int i = 1; i <= equ; i++)
            {
                if(i == k) 
                    continue;
                for(int j = col + 1; j <= val; j++)
                {
                    a[i][j] -= a[i][col]*a[k][j];
                }
                a[i][col] = 0.0;
            }
        }
        //扫描一下剩下的行,如果有解,则应全部都被消为了0
        for(k; k <= equ; k++)
        {
            if(!same(a[k][val], 0))
                return -1;
        }
        return val - k;
    }
}arr;

struct node
{
    int x, y, len;
    node(int a, int b, int l)
    {
        x = a, y = b;
        len = l;
    }
};
bool visited[20][20];
const int dx[] = {0, -1, 0, 1};
const int dy[] = {1, 0, -1, 0};

int toHash(int i, int j)
{
    return (i-1)*W + j;
}

bool judge(int x, int y)
{
    if( !visited[x][y] && x > 0 && x <= H && y > 0 && y <= W)
        return true;
    return false;
}

void init(int x, int y, int row)
{
    memset(visited, 0, sizeof(visited));
    queue<node> que;
    memset(visited, 0, sizeof(visited));
    que.push(node(x, y, 0));
    int has = 0;
    while(!que.empty())
    {
        node t = que.front();
        que.pop();
        if(t.len <= D && judge(t.x, t.y))
        {
            arr.a[row][toHash(t.x, t.y)] = 1.0;
            has++;
            for(int i = 0; i < 4; i++)
            {
                que.push(node(t.x+dx[i], t.y+dy[i], t.len+1));
            }
        }
        visited[t.x][t.y] = 1;
    }
    arr.a[row][W*H+1] = M[x][y]*has;
}

void solve()
{
    int cnt = 0;
    arr.equ = W*H;
    arr.val = W*H + 1;
    memset(arr.a, 0, sizeof(arr.a));
    for(int i = 1; i <= H; i++)
    {
        for(int j = 1; j <= W; j++)
        {
            init(i, j, ++cnt);
        }
    }
    arr.guass();
    int to = 1;
    for(int i = 1; i <= H; i++)
    {
        for(int j = 1; j <= W; j++)
        {
            printf("%8.2lf", arr.a[to++][W*H+1]);
        }
        printf("\n");
    }
}

int main()
{
    //freopen("input.txt", "r", stdin);
    bool flag = 0;
    while(scanf("%d%d%d", &W, &H, &D) != EOF)
    {
        if( !(W+H+D) )
            break; 
        if(flag)
            puts("");
        else
            flag = 1;
        for(int i = 1; i <= H; i++)
        {
            for(int j = 1; j <= W; j++)
            {
                scanf("%lf", &M[i][j]);
            }
        }
        solve();
    }
    return 0;
}

 

posted @ 2019-08-13 21:35  Dybala21  阅读(133)  评论(0编辑  收藏  举报