Canada Cup 2016 A,B,C,D,E

来源:互联网 发布:塞班版读书软件 编辑:程序博客网 时间:2024/06/04 19:18

【A】左右扫一遍,统计出和扫描方向不同的括号个数,最后求个和就是答案了。

【复杂度】O(len)

【B】水题,读清楚题是关键。

【复杂度】O(1)

【代码】

////Created by just_sort 2016/10/24//Copyright (c) 2016 just_sort.All Rights Reserved//#include <ext/pb_ds/assoc_container.hpp>#include <ext/pb_ds/tree_policy.hpp>#include <ext/pb_ds/hash_policy.hpp>#include <set>#include <map>#include <queue>#include <stack>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;using namespace __gnu_pbds;typedef long long LL;const int maxn = 200005;typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>order_set;//headLL n;char c;int main(){    while(scanf("%I64d%c",&n,&c)!=EOF)    {        getchar();        LL sum = 0;        sum = ((n-1)/4)*16;        LL t = n%4;        if(t % 2 == 0){            sum += 7;        }        if(c == 'f') sum += 1;        if(c == 'e') sum += 2;        if(c == 'd') sum += 3;        if(c == 'c') sum += 6;        if(c == 'b') sum += 5;        if(c == 'a') sum += 4;        cout<<sum<<endl;    }}

【C】给了一个字符数为27的字符串,这个字符串表示它是一个2*13的字符矩阵的一个通路,其中相邻的两个字符可以直接相邻也可以一个角相邻。

【解题方法】一个最关键的信息就是那个出现了两次的字符串,很容易发现只有当出现两次的字符串的左右位置相差>1的时候才有解,那么字符串左右位置之间的字符需要放到尾部,剩下的顺序放就可以了。

【复杂度】O(27)

【代码】

char a[30];char da[2][13];int v[30];int main(){    while(scanf("%s", a) != EOF)    {        memset(v, 0, sizeof(a));        int len = 27;        int l = -1, r = -1;        char two;        for(int i = 0; i < len; i++)        {            v[a[i]-'A']++;            if(v[a[i]-'A'] == 2) two = a[i];        }        for(int i = 0; i < len; i++)        {            if(a[i] == two)            {                if(l == -1) l = i;                else r = i;            }        }        //cout<<l<<" "<<r<<endl;        if(r - l == 1){            printf("Impossible\n");            continue;        }        int ans = (r -l -1)/2;        da[0][12-ans] = two;        for(int i = l + 1; i < len + l + 1; i++)        {            int x;            if(i == r) continue;            if(i >= len) x = i - len;            else x = i;            ans--;            if(ans >= 0) da[0][12-ans] = a[x];            else if(ans < 0 && ans >= -13) da[1][13+ans] = a[x];            else if(ans < -13) da[0][-14-ans] = a[x];        }        for(int i = 0; i < 2; i++)        {            for(int j = 0; j < 13; j++)                printf("%c",da[i][j]);            printf("\n");        }    }}

【D题意】给你n 个队伍,你的队伍是第一个队伍,每个队伍有气球数量,和最大数量。如果气球数量多于最大数量,你就会飞走,无法进行排名!你现在可以给你别的队伍气球,使得他们飞走,从而使你的排名尽量靠前!问你的最好名次?

【解题方法】

把比Limak队的气球数多的队伍都放入优先队列中,优先队列按照队伍还有几个球才能飞起,从小到大排序.剩下的对放入数组中,按照气球数从小到大排序.取出队列第一个元素,判断Limak的气球数是否能够让其飞起,若是,则队伍淘汰,更新Limak的气球数,把数组中比Limak对多的气球放入优先队列中,循环操作。

【代码】

struct node{    LL t, w;    bool operator<(const node &rhs) const{        return w - t + 1 > rhs.w - rhs.t + 1;    }};bool cmp1(const node &a, const node &b){    return a.t > b.t;}vector<node>v;priority_queue<node>q;int n;int main(){    while(scanf("%d",&n)!=EOF)    {        LL t, w;        while(!q.empty()) q.pop();        v.clear();        scanf("%I64d%I64d",&t,&w);        for(int i = 1; i < n; i++)        {            LL x, y;            scanf("%I64d%I64d",&x,&y);            if(x > t) q.push(node{x,y});            else v.push_back(node{x,y});        }        sort(v.begin(),v.end(),cmp1);        int ans = q.size()+1;        int l = 0;        while(!q.empty())        {            node cur = q.top();            if(cur.w - cur.t + 1 <= t)            {                t -= (cur.w - cur.t + 1);                q.pop();            }            else{                break;            }            for(l = l; l < v.size(); l++){                if(v[l].t > t) q.push(v[l]);                else break;            }            ans = min(ans, (int)q.size() + 1);        }        cout<<ans<<endl;    }}

【E】留坑,后续补。网上唯一的一篇blog,我还看不懂。http://blog.csdn.net/xl2015190026/article/details/52900297

0 0
原创粉丝点击