Codeforces Round #446 (Div. 2)

43 篇文章 0 订阅
30 篇文章 0 订阅

codeforces的分好久都没有变化了,而这场,修仙过度加上状态全无,降分没商量啊,来看看吧



A. Greed

思路:倾倒可乐,问能否将所有可乐倒入两个瓶子内

这个其实不要被题目内部剩余容量和总容量搞混淆就行了,并没有什么复杂计算,纯粹的水题

累加a计算总和,统计b,取最大值与次大值,然后比较就行了

很多时候,都是自己把事情搞复杂的

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>

using namespace std;

const int maxn = 1e5+10;

int a[maxn],b[maxn];

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        long long sum = 0;
        long long max1 = 0, max2 = 0;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
            sum += a[i];
        }
        for(int i=0;i<n;i++)
        {
            scanf("%d",&b[i]);
            if(b[i]>max2)
            {
                max2 = b[i];
            }
            if(max2>max1)
            {
                long long temp = max1;
                max1 = max2;
                max2 = temp;
            }
        }
        sum -= max1 + max2;
        if(sum>0)
        {
            printf("NO\n");
        }
        else
        {
            printf("YES\n");
        }
    }
    return 0;
}


B. Wrath

思路:这题有点类似于区间覆盖问题,每个点都可以向前覆盖一段距离,问有多少点没有被覆盖

其实这题思路也很清晰,按区间头排序,以一个指针向后便利,即可得到结果

就是要注意一下区间边界什么的,最后数组数据范围千万不能乱搞啊,大意失荆州

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>

using namespace std;

const int maxn = 1e6+10;

typedef struct KILL
{
    int st;
    int en;
}Kill;

Kill k[maxn];

bool cmp(const Kill &a, const Kill &b)
{
    if(a.st<b.st)
    {
        return true;
    }
    else
    {
        return false;
    }
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int sum = 0;
        int temp;
        scanf("%d",&temp);
        for(int i=1;i<n;i++,sum++)
        {
            k[sum].en = i - 1;
            scanf("%d",&temp);
            k[sum].st =  i - temp;
            if(k[sum].st<0)
            {
                k[sum].st = 0;
            }
            if(temp == 0)
            {
                sum--;
            }
        }
        //cout << sum << "*" << endl;
        sort(k,k+sum,cmp);
        int pos = 0;
        int re = 0;
        for(int i=0;i<sum&&pos<n;i++)
        {
            while(pos<k[i].st)
            {
                if(pos==n)
                {
                    break;
                }
                pos++;
                re++;
            }
            while(pos<=k[i].en)
            {
                if(pos==n)
                {
                    break;
                }
                pos++;
            }
            //cout << pos << "***" << endl;
        }
        re += n - pos;
        printf("%d\n",re);
        //cout << pos << endl;
        //cout << sum << "**" << endl;
    }
    return 0;
}

最后一题,最后1h+,直接睡着了,由于前两题做得太慢了,已经估计到了降分的悲剧,最后一题其实也是可做的,然而作息问题啊,最后有了思路,然而似乎写出了点bug没来得及交,看看吧

C. Pride

思路:这题一开始很难找到思绪,但其实这题的点就在,只要找到一个能最快使数组中出现1的方案即可,剩下的就是让这个1遍历遍数组就好了

一开始想的是,两个数的最大公约数为1,则可以在1的代价完成变换;如果两个最大公约数的最大公约数为1,则可以以3的代价变换,如此迭代把自己搞晕了

其实,这题可以直接寻找最少多少相邻的数最大公约数为1,来一个O(N^2)的暴力就解决了,根据数据范围想方案,所有想投机取巧的方法都用暴力代替

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>

using namespace std;

const int maxn = 2020;

int a[maxn],g[maxn];

int gcd(int a, int b)
{
    return b == 0 ? a : gcd(b, a % b);
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int sum = 0;
        /*bool s1 = false;
        bool s2 = false;*/
        int s = 0;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
            g[i] = a[i];
            if(a[i]>1)
            {
                sum++;
            }
            /*if(i>0)
            {
                g[i] = gcd(a[i],a[i-1]);
            }*/
        }
        //cout << sum << "*" << endl;
        //cout << s1 << "**" << s2 << endl;
        if(sum==n)
        {
            /*if(s1);
            else if(s2)
            {
                sum ++;
            }
            else
            {
                sum = -1;
            }*/
            for(s=1;s<n;s++)
            {
                int pos = n-1;
                for(;pos>=s;pos--)
                {
                    g[pos] = gcd(g[pos-1],a[pos]);
                    if(g[pos] == 1)
                    {
                        break;
                    }
                }
                if(pos >= s)
                {
                    break;
                }
            }
            if(s<n)
            {
                sum += s - 1;
            }
            else
            {
                sum = -1;
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}

这场实属可惜啊,题目完全可做,其实也算给自己敲一个警钟了吧,加油


文章地址:http://blog.csdn.net/owen_q/article/details/78629968

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值