zoukankan      html  css  js  c++  java
  • (算法)AA制

    题目:

    A、B、C、D四个人去吃大餐,吃饭去说好,付钱时AA制,但最后结账时,因为4个人带的钱不一样多,最后A付了112元,B付了86元,C付了10元,D没带钱,所以没有付;

    但AA制需要平摊餐费,所以需要设计一种方案来解决这个问题。

    现假设有n个人,m个人付款,请通过编程来解决这个问题(解决问题有多种方案,只需实现一种即可)

    思路:

    1、计算每个人本需要支付的钱,即平均数;

    2、计算实际上每个人的盈亏,即支付金额减去平均数;

    3、通过盈亏关系进行分配,即少付的将钱支付给多付的;

    以题目为例,平均数为52,减去平均数后的盈亏关系为:

    A:+60

    B:+34

    C:-42

    D:-52

    那么此时C、D需将钱支付给A和B,怎么支付呢?可以将问题转化为一下的矩阵形式:

      A B
    C    
    D    

    矩阵每个格子表示:x应该支付多少给y,从上到下依次填写表格,可以得到:

      A B
    C 42 0
    D 18 34

    代码:

    #include<iostream>
    #include<vector>
    using namespace std;
    
    const float EPSINON=0.00001;
    
    bool isZero(float x){
        return (x>=-EPSINON) && (x<=EPSINON);
    }
    
    int main(){
        int num_all;
        int num_paid;
        int num_unpaid;
        float sum,avg;
        int idx;
        float money;
    
        cout<< "Input number of people and number of who have paid: " <<endl;    
    
        while(cin >> num_all >> num_paid){
            vector<float> all(num_all,0.0);
    
            sum=0;
            for(int i=0;i<num_paid;i++){
                cin>>idx>>money;
                all[idx-1]=money;
                sum+=all[idx-1];
            }
            cout<<endl;
    
            avg=sum/num_all;
    
            vector<int> receive;
            vector<int> pay;
            
            for(int i=0;i<num_all;i++){
                all[i]-=avg;
                if(all[i]<0)
                    pay.push_back(i+1);
                if(all[i]>0)
                    receive.push_back(i+1);
            }
    
            int row=pay.size();
            int col=receive.size();
    
            vector<vector<float> > table(row,vector<float>(col,0.0));
    
            float from,to;
            for(int i=0;i<row;i++){
                for(int j=0;j<col;j++){
                    from=pay[i]-1;
                    to=receive[j]-1;
    
                    if(isZero(all[from]))
                        break;
    
                    if(isZero(all[to]))
                        continue;
    
                    if(all[from]+all[to]>=0){
                        table[i][j]=-all[from];
                        all[to]=all[from]+all[to];
                        all[from]=0.0;
                    }
                    else{
                        table[i][j]=all[to];
                        all[from]=all[from]+all[to];
                        all[to]=0.0;
                    }
                }
            }
    
            for(int i=0;i<row;i++){
                for(int j=0;j<col;j++){
                    cout<< table[i][j]<<" ";    
                }
                cout<<endl;
            }
            cout<<endl;
    
            for(int i=0;i<row;i++){
                for(int j=0;j<col;j++){
                    if(!isZero(table[i][j]))
                        cout<<pay[i]<<" paid "<<receive[j]<<" "<<table[i][j]<<endl;
                }
            }
        }
    
        return 0;
    }

     

     

     

  • 相关阅读:
    “连城决”——预示2008年手机营销体式格式新打破
    都会演出连城诀—诺基亚N78决战入手入手了!
    Lyx:阔别单调的 LaTeX 节制命令
    [转载]Oracle 11g R1下的自动内存经管(2)
    假造化手艺是决胜企业IT化的关头
    请各位博友对HyperV的运用终了指摘
    有199元的Office,还要用盗版吗?
    十一回南通,当晚和同学去小石桥附近的网吧
    Windows 消息
    WinAPI: 钩子回调函数之 MsgFilterProc
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4963349.html
Copyright © 2011-2022 走看看