zoukankan      html  css  js  c++  java
  • 18.8.15 考试总结

    买卖
    【问题描述】 小明找到了n个商店 小明 分别从第1个走到第n个。

    在每个商店中小明可以 :买入1个或0个物品A,若买入1个消耗 ai;

    卖出1个或 0物品 A,若卖出 ,若卖出1个获得bi.

    求小明在最后能获得的最大价值 。


    【输入格式】
    从文件buy.in 中输入数据。 第一行一个整数n。

    第二行n个整数,表示ai。 第三行n个整数,表示bi。


    【输出格式】
    输出到 文件 buy.out .out中。

    第一行一个整数n。 第二行n个整数,表示ai。 第三行n个整数,表示bi。

     

    这道题我一开始的贪心是错误的忘记考虑反悔的情况 

    后来发现这道题可以用网络流打暴力 可以狗四十分的

    但是不知道为什么除了第一个点都re 难过

    标程就是维护一个堆 每次走到一个i时的时候,我们就把i的买入价格推到堆里,

    如果点 i的卖出价格比前面还没买物品里最便宜要高  那么我们买入个最便宜的,

    然后在这卖出就可以获得利润 把堆顶弹出并更新答案 但是可能这样子配对并不是最优的

    所以就把b也压进去 以便反悔(b[j] - a[s] = b[j] - b[i] + b[i] - a[s])

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int N = 1e7;
    struct node {
        ll x;
        bool operator < (const node & a) const {
            return x > a.x;
        }
    };
    priority_queue<node>Q;
    ll a[N],b[N],ans;
    int n;
    
    int main( ) {
        
        freopen("buy.in","r",stdin);
        freopen("buy.out","w",stdout);
        scanf("%d",& n);
        for(int i = 1;i <= n;i ++) scanf("%I64d",& a[i]);
        for(int i = 1;i <= n;i ++) scanf("%I64d",& b[i]);
        for(int i = 1;i <= n;i ++) {
            
            node u,s; s.x = a[i];
            Q.push(s);
            u = Q.top( );
            if(u.x <= b[i]) {
                ans += b[i] - u.x;
                if(! Q.empty( )) Q.pop( ); 
                node ss; ss.x = b[i]; Q.push(ss);
            }    
        }
        printf("%I64d",ans);
    }

    投资
    【问题描述】
    OIER们投资了一 支股票 大家都知道股票有赚赔,现给出 n天里这支股票的涨跌情况 ,

    都为整数,涨为正 跌为负。

    OIER 们想知道天数在s到e之间的这只股票涨跌最大连续和 。


    【输入格式 】
    从文件 invest.in中输入数据。 第一行有三个正整数 n、s和 e ,同上描述。 接下来有n行,每一个整数 ai ,组成数列的顺序不 可以变换。


    【输出格式】
    输出到文件invest.out中。输出长度在s和e之间连续的数列数的和的最大值。

     

    做的时候用的滑动窗口 结果wa了60分 不如打暴力...。

    正解是维护最大前缀和 对于一个起点来说合法的串是i +s~i + e

    所以在这个区间内用线段树维护一个最大前缀和 再减去sum[i - 1]即可

    代码

    #include <bits/stdc++.h>
    #define oo 1000000000
    using namespace std;
    
    typedef long long ll;
    const int N = 1e6 + 5;
    ll ans,sum[N],f[4 * N];
    int n,s,e,a[N],que[2 * N],head,tail;
    
    void update(int o) {
        
        f[o] = max(f[2 * o],f[2 * o + 1]);
    }
    
    void build(int o,int l,int r) {
        
        if(l == r) {
            f[o] = sum[l];
            return ;
        }
        int mid = (l + r) >> 1;
        build(2 * o,l,mid);
        build(2 * o + 1,mid + 1,r);
        update(o);
    }
    
    ll query(int o,int l,int r,int L,int R) {
        
        if(l >= L && r <= R) return f[o];
        int mid = (l + r) >> 1;
        ll ans = -oo;
        if(L <= mid) ans = max(ans,query(2 * o,l,mid,L,R));
        if(mid < R) ans = max(ans,query(2 * o + 1,mid + 1,r,L,R));
        return ans;
    }
    
    int main( ) {
        
        freopen("invest.in","r",stdin);
        freopen("invest.out","w",stdout);
        scanf("%d%d%d",& n,& s,& e);
        for(int i = 0;i < 4 * N;i ++) f[i] = -oo;
        for(int i = 1;i <= n;i ++) {
            scanf("%d",& a[i]);
            sum[i] = sum[i - 1] + a[i];
        }
        ans = -oo;
        build(1,1,n);
        for(int i = 1;i <= n;i ++) {
            if(i + s - 1 > n) break;
            ll qq = query(1,1,n,i + s - 1,min(i + e - 1,n));
            ans = max(ans,qq - sum[i - 1]);
        }
        printf("%I64d",ans);
        return 0;
    }

    游戏
    【问题描述】
    艾利斯顿商学院篮球队要参加一年度的市比赛了。拉拉队是篮球比赛的一个看点,

    好队往能帮助球增加士气赢得最终比赛。所以作为队长的楚雨荨同学知道,

    帮助篮球训练好有多么重要。选拔工作已经结束, 在雨荨和校长挑选下n位集优秀的身材、

    舞技于一体的美女从众多报名生中脱颖而出。这些将随着篮球队小伙子们一起,和对手抗衡,

    为艾利斯顿篮球队加油助威。一个阳光明媚的早晨雨荨带领队员们开始了排练。

    n个女生从左到右排成一行,每人手中都举了写 有 26 个小写字母中的某一牌子,

    在比赛时候挥舞为伙们呐喊、加油。雨荨发现,

    如果连续的一段女生有奇数个并且他们手中牌子所写字母,从左到右和读起来一样,

    那么这段女生就被称作和谐小群体。现在雨荨想找出所有和谐小群体,

    并且按照女生的个数降序排之后前K个和谐小群体的女生个数乘积是多少。由于答案可能很大,

    雨荨只要你告诉她谐小群体的女生个数乘积是多少。由于答案可能很大,

    雨荨只要你告诉她案除以 19930726 的余数是多少就行了。


    【输入格式】
    从文件rehearse .in 中输入 数据。
    第一行为两个正整数 n和 K,代表的东西在题目描述中已经叙。接下来一 行为 n个字符,

    代表从左到右女生拿的牌子上写母。


    【输出格式】
    输出到文件rehearse .out .out中。 输出一个整数,

    代表题目描述中所写的乘积除以 19930726 的余数,如果总 的和谐小群体个数于 K,输出一个整数 -1。

     

    考试的时候基本是把正解给弄出来了的 然而我没写过manacher 我就自己乱yy了一个

    wa了好几个点 t了3个点 还有统计答案的时候不够优秀 

    答题思路就是manacher + 差分树状数组 + 快速幂

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int N = 1e6 + 5;
    const ll mod = 19930726;
    int n,f[N],t[N],mi,cent = 0;
    char s[N];
    ll c[N],k;
    
    int lowbit(int i) {
        
        return (i)&(-i);
    }
    
    void add(int pos,ll val) {
        
        while(pos <= n) {
            c[pos] += val;
            pos += lowbit(pos);
        }
    }
    
    ll query(int pos) {
        
        ll ans = 0;
        while(pos >= 1) {
            ans += c[pos];
            pos -= lowbit(pos);
        }
        return ans;
    }
    
    ll fast_pow(ll a,ll b) {
        
        ll ans = 1;
        for(;b;b >>= 1,a = (a * a) % mod)
            if(b & 1) ans = (ans * a) % mod;
        return ans; 
    }
    
    void manacher( ) {
        
        s[0] = '-'; s[n + 1] = '+';
        for(int i = 1;i <= n;i ++) {
            if(i <= mi)        f[i] = min(mi - i, f[cent * 2 - i]);
            else    f[i] = 0;
            while(s[i - f[i] - 1] == s[i + f[i] + 1])    f[i]++;
            if(i + f[i] > mi) {
                mi = i + f[i];
                cent = i;
            }
            add(1,1); add(1 + f[i] * 2 + 1,-1);
        }
    }
    
    void solve( ) {
        
        ll sum = 0,ans = 1;
        int st = n;
        if(st % 2 == 0) st --;
        for(int i = st;i >= 1;i -= 2) {
            ll num = query(i);
            if(sum + num >= k) {
                ans = ans * fast_pow(i,k - sum) % mod;
                sum = k;
                printf("%I64d",ans); break;
            }
            else {
                ans = ans * fast_pow(i,num) % mod;
                sum += num;
            }
        }
        if(sum < k) printf("-1");
    }
    
    int main( ) {
        
        freopen("rehearse.in","r",stdin);
        freopen("rehearse.out","w",stdout);
        scanf("%d%I64d",& n,& k);
        scanf("%s",s + 1);
        manacher( );
        solve( );
    }
  • 相关阅读:
    东芝线阵CCD芯片TCD1305DG驱动时序设计
    数字电路中应避免产生不必要的锁存器 Latch
    准双向口、开漏输出、推挽输出结构介绍
    边沿检测电路小结
    数字系统中的亚稳态及其解决办法
    launch edge 和 latch edge 延迟
    基于Verilog的偶数、奇数、半整数分频以及任意分频器设计
    找到了救命的东西 NVIDIA MPS (multi-process service)
    关于多个程序同时launch kernels on the same GPU
    java的System.currentTimeMillis()和System.nanoTime()
  • 原文地址:https://www.cnblogs.com/Rubenisveryhandsome/p/9482772.html
Copyright © 2011-2022 走看看