数论 HihoCoder1195 高斯消元

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/DADDY_HONG/article/details/81985956

#1195 : 高斯消元·一

时间限制:10000ms

单点时限:1000ms

内存限制:256MB

描述

小Ho:喂不得了啦,那边便利店的薯片半价了!

小Hi:啥?!

小Ho:那边的便利店在打折促销啊。

小Hi:走走走,赶紧去看看=v=

于是小Hi和小Ho来到了便利店。

老板为了促销,推出了组合包的形式,将不同数量的各类商品打包成一个组合,顾客可以选择组合进行购买。比如2袋薯片,1听可乐的组合只要5元,而1袋薯片,2听可乐的组合只要4元。

通过询问老板,小Hi和小Ho知道:一共有N种不同的商品和M种不同的商品组合;每一个组合的价格等于组合内商品售价之和,一个组合内同一件商品不会超过10件。

小Hi:这样算下来的话,一听可乐就是1元,而一包薯片是2元。小Ho,如果你知道所有的组合情况,你能分别算出每一件商品单独的价格么?

小Ho:当然可以了,这样的小问题怎么能难到我呢?

   

提示:高斯消元

输入

第1行:2个正整数,N,M。表示商品的数量N,组合的数量M。1≤N≤500, N≤M≤2*N

第2..M+1行:N+1个非负整数,第i+1行第j列表示在第i个组合中,商品j的数量a[i][j]。第i+1行第N+1个数表示该组合的售价c[i]。0≤a[i][j]≤10, 0≤c[i]≤10^9

输出

若没有办法计算出每个商品单独的价格,输出"No solutions"

若可能存在多个不同的结果,输出"Many solutions"

若存在唯一可能的结果,输出N行,每行一个非负整数,第i行表示第i个商品单独的售价。数据保证如果存在唯一解,那么解一定恰好是非负整数解。

样例输入

2 2
2 1 5
1 2 4

样例输出

2
1

嘤嘤嘤,线代不好好学很惨的嘤!

高斯消元嘛,就求对角线方程组,嘛

按照提示一步步写就好辣:

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;

const int maxn=520;
const int maxm=1020;
const double eps=1e-6;

int n,m;
double matrix[maxm][maxn];

int gauss()
{
    int ans=1;
    //处理出上三角矩阵x)//处理出对角线矩阵
    for(int i=0;i<n;++i){   //<n不算最后一列//列从左往右遍历可以保证当前列左边都为0且消元不受影响
        int p=i;
        for(int j=i;j<m;++j){
            if(fabs(matrix[j][i])>fabs(matrix[p][i]))
                p=j;
        }
        swap(matrix[i],matrix[p]);
        //以上代码进行行交换将对角线上的matrix[i][i]设为i行下绝对值最大的
        //若仍然无法使matrix[i][i]不为0(秩<n的情况),存在多个解
        if(fabs(matrix[i][i])<eps){
            ans=-1;
            continue;
        }
        //i行除以matrix[i][i],matrix[i][i]变为1
        for(int j=i+1;j<=n;++j)     //<=n算最后一列
            matrix[i][j]/=matrix[i][i];
        //消除第i列除第i行的数
        for(int j=0;j<m;++j){
            if(i!=j){
                for(int k=i+1;k<=n;++k){    //<=n算最后一列
                    matrix[j][k]-=matrix[j][i]*matrix[i][k];
                }
            }
        }
    }
    //若存在0=y的情况,无解
    for(int i=0;i<m;++i){
        //注意分n行前n行后的
        if(fabs(matrix[i][n])>eps&&(i>=n||i<n&&fabs(matrix[i][i])<eps)){
            ans=0;
            return ans;
        }
    }
    return ans;
}

int main()
{
    while(~scanf("%d%d",&n,&m)){
        for(int i=0;i<m;++i){
            for(int j=0;j<=n;++j){
                scanf("%lf",&matrix[i][j]);
            }
        }
        int ans=gauss();
        if(!ans)
            printf("No solutions\n");
        else if(ans==-1)
            printf("Many solutions\n");
        else
            for(int i=0;i<n;++i)
                printf("%d\n",(int)round(matrix[i][n]));    //注意要四舍五入!
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/DADDY_HONG/article/details/81985956