CodeForces 839B

我发现出给新人的题目全是毒瘤题...就比如这个题目,我虽然做出来了,但是他妈一点快感没有...有的就是来自出题人的智商压制....唉,真烦....

这个题目我们回过头来看一看,其实也就是那样把....一开始我的思路是除8,除4,除2,用这三个余数来思考的,但是这个思路发现要考虑的细节太多了,根本不好实现,然后我们就决定了我们的贪心策略就是首先把四个一排的塞满,然后再塞2个的...

我们每个组的人数大于3的时候,我们给他分配一个4排,如果四排连坐不够了,分配2个2连坐的...

经过上面的操作,我们剩余的人数只剩下0 1 2三种情况,然后可以分配4连坐,2连坐,很明显,我们首先分配2连坐;

2两座分配完了,我们只有4连坐,这里就要分析了:

4连坐可以怎么做呢?2+1或者1+1

2+1一开始我是考虑到了,但是1+1没有考虑,wa很久;

还有就是2+1是怎么来的?这里记录两个,一个是4座剩余的数量,还有一个是做一个2人的,就要少一个完整的4个...如果这两个变量没变的话,相等的话,我们就相当于没经历过这个过程,这个要注意,我们最后求的时候要分开来算的...大家画一个图就比较清楚了...

//
// Created by 唐律 on 2017/11/15.
//
#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;

int main() {
    int n, k;
    scanf("%d%d", &n, &k);
    int sum = 0;
    int a[105];
    for (int i = 1; i <= k; i++)
        scanf("%d", &a[i]);

    int four = n;
    int two = n * 2;
    for (int i = 1; i <= k; i++) {
        if (a[i] >= 3)//在第一轮中,我们把所有大于3的情况先筛选出来
        {
            int temp4 = a[i] / 4;//当前的a[i]需要几个4排连坐
            if (temp4 <= four) //我们目前剩余的4排座位还够
            {
                four = four - temp4;
                a[i] = a[i] - temp4 * 4;//把这些人安排4个位置后还剩下多少
                if (a[i] == 3)//如果还剩下三个
                {
                    if (four >= 1)//优先分配4座连的
                    {
                        a[i] = 0;
                        four--;
                    }
                    else if (four < 1)//4座连的位置不够了,只有分配两座
                    {
                        if (two >= 2) {
                            a[i] = 0;
                            two = two - 2;
                        } else {
                            printf("NO\n");
                            return 0;
                        }
                    }
                }
            }

            else if (four < temp4)//4排的位置不够了
            {
                a[i] = a[i] - four * 4;
                four = 0;//我们优先安排我们的4个人的位置
                if(a[i] >= 3)//我们把这些4连坐的位置分配完了,如果还剩下三个人
                {
                    int temp2 = a[i] / 2;
                    a[i] = a[i] - temp2 * 2;
                    if (temp2 <= two) {
                        two = two - temp2;
                    }
                    else if (temp2 > two) {
                        printf("NO\n");
                        return 0;
                    }
                }
            }
        }
    }

    //经过我们的第一轮之后,我们所有组未分配的人数只有三种情况:0,1,2.
    //还是和上面的思路一样,我们优先分配我们2个人的情况
    int four1 = four;
    int flag = 0;
    for( int i = 1; i <= k; i++ )
    {
        if( a[i] == 2 )
        {
            if( two >= 1 )
            {
                a[i] = 0;
                two--;
                continue;
            }

            else if( two == 0 )
            {
                if( four >= 1 )
                {
                    four--;
                    a[i] = 0;
                    continue;
                }

                if( four1 >= 1 )
                {
                    four1--;
                    a[i] = 1;
                    flag = 1;
                    continue;
                }
                else
                {
                    printf("NO\n");
                    return 0;
                }
            }
        }
    }

    if( flag == 0 )
    {
        if(four1 == four)
            sum = four * 2 + two;
        else
            sum = four1*2+four+two;
    }

    else if( flag == 1)
    {
        sum = four1 + two;
    }
    int left = 0;
    for( int i = 1; i <= k; i++ )
        if(a[i] == 1)
            left++;
    if( sum < left)
        printf("NO\n");
    else
        printf("YES\n");
}

 

posted @ 2017-11-17 14:38  fzfn5049  阅读(191)  评论(0编辑  收藏  举报