zoukankan      html  css  js  c++  java
  • 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("
    ");
        }
    }
    
    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;
    }
  • 相关阅读:
    日志到底该如何打印?
    消息摘要(MessageDigest)
    URL编码及解码原理
    AES简介
    MySQL中整型长度的意义
    keytool生成密钥
    证书类型及秘钥库
    Base64编码及解码原理
    Holistically-Nested Edge Detection 论文总结
    全新bili主题
  • 原文地址:https://www.cnblogs.com/dybala21/p/11348751.html
Copyright © 2011-2022 走看看