hdu3359 约旦高斯消元法

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define eps 1e-8
using namespace std;
double a[222][222];
double A[222][222];
int h,w,d,id;
bool inmap(int x,int y)
{
    if(0<=x&&x<h&&0<=y&&y<w) return true;
    else return false;
}
void f(int n,int x,int y)
{
    int num=0;
    for(int i=x-d;i<=x+d;i++)
    {
        int k=d-abs(i-x);
        for(int j=y-k;j<=y+k;j++)
        {
            if(inmap(i,j))
            {
                num++;
                A[n][i*w+j]=1;
            }
        }
    }
    A[n][w*h]=a[x][y]*num;
}
void build()
{
    memset(A,0,sizeof(A));
    id=0;
    for(int i=0;i<h;i++)
    {
        for(int j=0;j<w;j++)
        {
            f(id++,i,j);
        }
    }
}
void gaosi_jodan(int n)
{
    for(int i=0;i<n;i++)
    {
        int r=i;
        for(int j=i+1;j<n;j++)
        {
            if(fabs(A[j][i])>fabs(A[r][i]))//找最大行
            {
                r=j;
            }
        }
        if(fabs(A[r][i])<eps) continue;
        if(r!=i)
        {
            for(int j=0;j<=n;j++) swap(A[r][j],A[i][j]);
        }
        for(int k=0;k<n;k++)
        {
            if(k!=i&&fabs(A[k][i])>eps)
            {
                for(int j=n;j>=i;j--)
                {
                    A[k][j]-=A[i][j]*A[k][i]/A[i][i];
                }
            }
        }
    }
}
int main()
{
    bool flag=true;
    while(scanf("%d%d%d",&w,&h,&d),h)
    {
        if(flag) flag=false;
        else puts("");
        for(int i=0;i<h;i++)
        {
            for(int j=0;j<w;j++)
            {
                scanf("%lf",&a[i][j]);
            }
        }
        build();
        gaosi_jodan(id);
        for(int i=0;i<h;i++)
        {
            for(int j=0;j<w;j++)
            {
                printf("%8.2lf",A[i*w+j][id]/A[i*w+j][i*w+j]);
            }
            printf("\n");
        }
    }
    return 0;
}

你可能感兴趣的:(hdu3359 约旦高斯消元法)