Skip to content

11009: 【原1009】二哥炒股票

题目

题目描述

author: xjia 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/1009

题目描述

二哥需要一个能根据交易记录和股票价格记录统计出先进收益的程序。

现金收益包括两部分,一部分是卖出收入,一部分是每次交易需要支出的费用。卖出收入就是卖出股票获得的总收入减去买入的总支出。股票的价格是按每股的价格给出的,而交易的最小单位是“一手”,每手是100股。每次买入的费用如下所述:

  1. 佣金,收取交易额的0.2%,但最低的收取标准是5元。比如买入总金额为1000元的股票,实际佣金是2元,但不超过5元,所以按5元收取。

  2. 过户费,每一千股收取1元。

  3. 通讯费,由于二哥在上海,每次只收取本地交易费用1元。

每次卖出的费用标准与买入一致,但还要加收证券印花税(交易额的0.1%)。

另外,二哥是个专一的人,他只对一支股票感兴趣。

输入格式

输入分为两部分,第一部分是二哥的交易记录,第二部分是股票价格记录。

交易记录的第一行是一个正整数m,表示共有m个交易动作。每个交易动作占一行,包括三个正整数t, a和d, d = 1时,表示在时间t买入该股票a手,当d = 2时,表示在时间t卖出该股票a手。记录信息保证有意义;d不会取其他值。

股票价格记录的第一行是一个正整数n,表示共有n次价格变动。每次价格变动占一行,包括两个正整数t和v,表示在时间t该股票的价格变为v元每股。价格变动过程是按时间顺序给出的,第一次价格变动之前不会发生交易;t使用的是一个虚拟的时间量度,在时间t进行的交易按价格v计算。

输出格式

输出二哥的现金收益,保留两位小数(四舍五入)。

说明

对于所有数据:\(m \leq 50 \), \(v \leq 200 \), \( a \leq 200 \)

对于70%的数据:\(n \leq 100 \) , \(t \leq 10000 \)

对于30%的数据:\(n \leq 10000 \) , \( t \leq 100000000 \)

Sample Input

2
15 50 1
40 30 2
4
10 100
20 90
30 95
40 102

Sample Output

-195928.00

FineArtz's solution

/* 二哥炒股票 */
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;

const int EndOfTrade = 100000005;
struct TradeRecord{
    //constructor
    TradeRecord() : t(0), a(0), d(0) {};
    TradeRecord(const TradeRecord &TR) : t(TR.t), a(TR.a), d(TR.d) {}
    int t, a;
    short d;
};

double profit(const TradeRecord &trade, const int &v){
    double ret = 0.0;
    if (trade.d == 1){
        double outcome = 100.0 * v * trade.a;
        outcome += (outcome - 2500 > -1e-6) ? outcome * 0.002 : 5.0;
        outcome += trade.a / 10.0;
        outcome += 1.0;
        ret -= outcome;
    }
    else{
        double income = 100.0 * v * trade.a;
        double t = income;
        income -= t * 0.001;
        income -= (t - 2500 > -1e-6) ? t * 0.002 : 5.0;
        income -= trade.a / 10.0;
        income -= 1.0;
        ret += income;
    }
    return ret;
}

int main(){
    TradeRecord tr[55];
    int m = 0;
    cin >> m;
    for (int i = 1; i <= m; ++i){
        cin >> tr[i].t >> tr[i].a >> tr[i].d;
    }
    int n = 0;
    cin >> n;
    int t[10005], v[10005];
    for (int i = 1; i <= n; ++i)
        cin >> t[i] >> v[i];
    int j = 1;
    double NetProfit = 0.0;
    for (int i = 1; i <= n; ++i){
        if (t[i] < tr[j].t) continue;
        while (j <= m && tr[j].t < t[i]){
            NetProfit += profit(tr[j], v[i - 1]);
            ++j;
        }
        if (j > m) break;
    }
    for (int i = j; i <= m; ++i){
        NetProfit += profit(tr[i], v[n]);
    }
    cout << setiosflags(ios::fixed) << setprecision(2) << NetProfit << endl;
    return 0;
}

ligongzzz's solution

#include <iostream>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <functional>
using namespace std;

typedef pair<int, int> pii;

class type {
public:
    int t, a, d;
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int m, n;
    cin >> m;
    vector<type> buy_data(m);

    for (int i = 0; i < m; ++i) {
        cin >> buy_data[i].t >> buy_data[i].a >> buy_data[i].d;
    }

    cin >> n;
    vector<pair<int, int>> val_data(n);
    for (int i = 0; i < n; ++i)
        cin >> val_data[i].first >> val_data[i].second;

    function<bool(const pii&,const pii&)> cmp = [](const pair<int, int>& a,const pair<int, int>& b) {
        return a.first < b.first;
    };

    sort(buy_data.begin(), buy_data.end(), [](type& a, type& b) {return a.t < b.t; });
    sort(val_data.begin(), val_data.end(), cmp);

    double ans = 0.0;
    for (int i = 0, j = 0; i < m; ++i) {
        for (; j < n - 1 && buy_data[i].t >= val_data[j + 1].first; ++j);
        if (buy_data[i].d == 1) {
            double cur_num = 100.0 * buy_data[i].a * val_data[j].second;
            ans -= cur_num * 0.002 > 5.0 ? cur_num * 0.002 : 5.0;
            ans -= 1.0 * buy_data[i].a / 10;
            ans -= 1.0;
            ans -= cur_num;
        }
        else {
            double cur_num = 100.0 * buy_data[i].a * val_data[j].second;
            ans -= cur_num * 0.002 > 5.0 ? cur_num * 0.002 : 5.0;
            ans -= 1.0 * buy_data[i].a / 10;
            ans -= 1.0;
            ans += cur_num;
            ans -= cur_num * 0.001;
        }
    }

    cout << fixed << setprecision(2) << ans;

    return 0;
}

yyong119's solution

#include <iostream>

#include <iomanip>

using namespace std;

int main(){

    int m,n;

    cin>>m;

    int trade_time[m],trade_num[m],trade_state[m];

    for(int i=0;i<m;++i)

        cin>>trade_time[i]>>trade_num[i]>>trade_state[i];

    cin>>n;

    int change_time[n],change_money[n];

    for(int i=0;i<n;++i)

        cin>>change_time[i]>>change_money[i];

    int i=0,j=0,per_money;

    double income=0.0;

    for(;i<m;++i){

        for(j=0;j<n-1;++j)

            if(change_time[j]<=trade_time[i]&&change_time[j+1]>trade_time[i])

                break;

        per_money=trade_num[i]*change_money[j]*100;

        income+=(trade_state[i]*2-3)*per_money;

        income-=((per_money*0.002)>5?(per_money*0.002):5);

        income-=trade_num[i]/10.0;

        income-=1;

        income-=(trade_state[i]-1)*per_money*0.001;

    }

    cout<<fixed<<setprecision(2)<<income<<endl;

}