watermelon E题 2019年湘潭大学程序设计竞赛(重现赛)(牛客网)

我还是尽量修改一下吧;大家先别看了;

https://ac.nowcoder.com/acm/contest/893?&headNav=www#question

这个只需登录一下就能够看到题目,所以我就不把题目展示给大家了;这个题首先我没做出来;然后看了一下题解,想了好长时间,才有点懂了;

下面是题解:

两点

写法简单一点是O(m),复杂一点是O(n),两种都可以过

O(m)的方法:循环维护到每个人吃西瓜时的西瓜数量的区间[L,R]

初始L=R=m

对于非肚量最大的人L每次减一(至少吃一个),R每次减去能a[i](至多吃a[i]个)

对于肚量最大的人L和R都减去a[i]

直到某个非肚量最大的人吃西瓜的时候如果L<0,得到答案为No

或者肚量最大的人吃西瓜时R<0,那么说明可以成功,得到答案为Yes

O(n)方法类似,求出肚量最大的人之前和之后的人的肚量之和即可优化。

 

这个我的理解是区间问题;先看一下代码吧;我直接从AC的代码中找到一个有意思的代码复制过来了;

/**
 *        ┏┓    ┏┓
 *        ┏┛┗━━━━━━━┛┗━━━┓
 *        ┃       ┃  
 *        ┃   ━    ┃
 *        ┃ >   < ┃
 *        ┃       ┃
 *        ┃... ⌒ ...  ┃
 *        ┃       ┃
 *        ┗━┓   ┏━┛
 *          ┃   ┃ Code is far away from bug with the animal protecting          
 *          ┃   ┃   神兽保佑,代码无bug
 *          ┃   ┃           
 *          ┃   ┃        
 *          ┃   ┃
 *          ┃   ┃           
 *          ┃   ┗━━━┓
 *          ┃       ┣┓
 *          ┃       ┏┛
 *          ┗┓┓┏━┳┓┏┛
 *           ┃┫┫ ┃┫┫
 *           ┗┻┛ ┗┻┛
 */
// warm heart, wagging tail,and a smile just for you!
//
//                            _ooOoo_
//                           o8888888o
//                           88" . "88
//                           (| -_- |)
//                           O\  =  /O
//                        ____/`---'\____
//                      .'  \|     |//  `.
//                     /  \|||  :  |||//  \
//                    /  _||||| -:- |||||-  \
//                    |   | \\  -  /// |   |
//                    | \_|  ''\---/''  |   |
//                    \  .-\__  `-`  ___/-. /
//                  ___`. .'  /--.--\  `. . __
//               ."" '<  `.___\_<|>_/___.'  >'"".
//              | | :  `- \`.;`\ _ /`;.`/ - ` : | |
//              \  \ `-.   \_ __\ /__ _/   .-` /  /
//         ======`-.____`-.___\_____/___.-`____.-'======
//                            `=---='
//        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//                     佛祖保佑      永无BUG
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
 
typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const int BufferSize = 1 << 16;
char buffer[BufferSize], *head, *tail;
inline char Getchar()
{
    if(head == tail) {
        int l = fread(buffer, 1, BufferSize, stdin);
        tail = (head = buffer) + l;
    }
    return *head++;
}
inline int read() 
{
    int x = 0, f = 1; char c = Getchar();
    for(; !isdigit(c); c = Getchar()) if(c == '-') f = -1;
    for(; isdigit(c); c = Getchar()) x = x * 10 + c - '0';
    return x * f;
}
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
const LL INFLL = 0x3f3f3f3f3f3f3f3f;
int a[maxn];
int main() 
{
#ifndef ONLINE_JUDGE
    FIN
#endif
    int T;
    scanf("%d", &T);
    while(T--) 
	{
        int n, m;
        scanf("%d%d", &n, &m);
        LL sum = 0;
        int maxx = -1;
        int pos;
        for(int i = 0; i < n; i++) 
		{
            scanf("%d", &a[i]);
            if(a[i] > maxx)
			{
                maxx = a[i];
                pos = i;
            }
            sum += a[i];
        }
        LL l  = m;
        LL r = m;
        int flag = 0;
        for(int i = 0;; i++)
		{
            i %= n;
            if(i == pos) 
			{
                if(l <= 0) 
				{
                    flag = 1;
                    break;
                }
                l -= a[i];
                r -= a[i];
            } 
			else 
			{
                if(r <= 0) 
				{
                    flag = 0;
                    break;
                }
                l -= a[i];
                r--;
            }
        }
        if(flag) 
		{
            printf("YES\n");
        }
		else
		{
        	
            printf("NO\n");
        }
    }
    return 0;
}

这个代码中的l和r和题解中的l 和 r位置正好相反;

我是按照题解来解释的;

对于这个题,我们可以这样想,就是取最大值和最小值,最大是每个人吃ai个西瓜,最少是每个人吃1个西瓜,也就是每次每个人吃1个西瓜;当然肚量最大的那个人每次吃最多西瓜;

从这个代码中我们可以看出,让这个循环结束的条件有两个,1是当每个人吃一个西瓜的时候,还有没轮到肚量最大的那个人吃的时候结束了,证明不可以被套路;2  是当每个人吃·ai(也就是每个人可以吃的最大个)西瓜的时候,此时可以吃的西瓜为每次加上 ai;

只要到 最大肚量的那个人之前,r>0并且l<0;这样就可以套路他;

题解大体就是这个意思,我感觉自己说的不是很清楚;当然那个o(m)的方法,也是这个思路;

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值