Technocup 2017 - Elimination Round 1 (Rated for Div. 2) D. T-shirts Distribution 贪心、flows

129 篇文章 0 订阅
58 篇文章 0 订阅

D. T-shirts Distribution
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

The organizers of a programming contest have decided to present t-shirts to participants. There are six different t-shirts sizes in this problem: SMLXLXXLXXXL (sizes are listed in increasing order). The t-shirts are already prepared. For each size from S to XXXLyou are given the number of t-shirts of this size.

During the registration, the organizers asked each of the n participants about the t-shirt size he wants. If a participant hesitated between two sizes, he could specify two neighboring sizes — this means that any of these two sizes suits him.

Write a program that will determine whether it is possible to present a t-shirt to each participant of the competition, or not. Of course, each participant should get a t-shirt of proper size:

  • the size he wanted, if he specified one size;
  • any of the two neibouring sizes, if he specified two sizes.

If it is possible, the program should find any valid distribution of the t-shirts.

Input

The first line of the input contains six non-negative integers — the number of t-shirts of each size. The numbers are given for the sizes S,MLXLXXLXXXL, respectively. The total number of t-shirts doesn't exceed 100 000.

The second line contains positive integer n (1 ≤ n ≤ 100 000) — the number of participants.

The following n lines contain the sizes specified by the participants, one line per participant. The i-th line contains information provided by the i-th participant: single size or two sizes separated by comma (without any spaces). If there are two sizes, the sizes are written in increasing order. It is guaranteed that two sizes separated by comma are neighboring.

Output

If it is not possible to present a t-shirt to each participant, print «NO» (without quotes).

Otherwise, print n + 1 lines. In the first line print «YES» (without quotes). In the following n lines print the t-shirt sizes the orginizers should give to participants, one per line. The order of the participants should be the same as in the input.

If there are multiple solutions, print any of them.

Examples
input
0 1 0 1 1 0
3
XL
S,M
XL,XXL
output
YES
XL
M
XXL
input
1 1 2 0 1 1
5
S
M
S,M
XXL,XXXL
XL,XXL
output
NO


Source

Technocup 2017 - Elimination Round 1 (Unofficially Open for Everyone, Rated for Div. 2)


My Solution

题意:给出 S,MLXLXXLXXXL 每种衣服的个数,然后给出每个人的选择,可能只有一种,可能2种中的任一种即可(且只能是大小相邻的两种,且这2种输入的时候是升序排列),求给出的那些衣服能否合理的分配给这些人,如果可以给出具体分配方案。


贪心、flows

首先把只有一种情况的直接处理掉,

然后对有2种选择的进行贪心

从S开始从左向右贪,因为单一选择的已经处理掉,比如那剩下的sz["S"]只能用来处理S,M的情况了,所以优先用sz["S"](左边的)来处理S,M,依次类推优先使用左边的。

在读入的时候把2种选择的情况,按照前一种储存,但用flag布尔数组标记为true,处理时候,每次处理完后把该地方的true更新为false;

即扫到v[j] == i && flag[j] == true

如果sz[i]的那种还有则使用sz[i]的那种 sz[i]--;  flag[j] = false;

如果sz[i]的那种没有了则使用右边的那种sz[i+1]--; v[j] = i + 1; flag[j] = false;

处理完后,扫一遍sz数组看是否有负数,扫一遍flag数组看是否有未处理的位置。

然后依次输出就好了

复杂度 O(n)


#include <iostream>
#include <cstdio>
#include <string>
#include <map>
#include <cstring>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 8;

int sz[8], v[maxn];
map<string, int> mp1;
map<int, string> mp2;
string s, s1;
bool flag[maxn];

int main()
{
    #ifdef LOCAL
    freopen("d.txt", "r", stdin);
    //freopen("d.out", "w", stdout);
    int T = 4;
    while(T--){
    #endif // LOCAL
    ios::sync_with_stdio(false); cin.tie(0);

    mp1["S"] = 1, mp1["M"] = 2, mp1["L"] = 3;
    mp1["XL"] = 4, mp1["XXL"] = 5, mp1["XXXL"] = 6;

    mp2[1] = "S", mp2[2] = "M", mp2[3] = "L";
    mp2[4] = "XL", mp2[5] = "XXL", mp2[6] = "XXXL";

    for(int i = 1; i <= 6; i++){
        cin >> sz[i];
    }

    int n, i, j, len;
    cin >> n;
    s1.clear();
    for(i = 0; i < n; i++){
        cin >> s;
        if(mp1[s] != 0){
            sz[mp1[s]]--;
            v[i] = mp1[s];
        }
        else{
            len = s.size();
            for(j = 0; j < len; j++){
                if(s[j] != ',') s1 += s[j];
                else break;
            }
            v[i] = mp1[s1];
            flag[i] = true;
            s1.clear();
        }
    }

    bool ans = true;

    for(i = 1; i <= 6; i++){
        if(sz[i] < 0){
            ans = false;
            break;
        }
        for(j = 0; j < n; j++){
            if(sz[i] <= 0) break;
            if(v[j] == i && flag[j]){
                sz[i]--;
                flag[j] = false;
            }
        }
        for(; j < n; j++){
            if(v[j] == i && flag[j]){
                sz[i+1]--;
                v[j] = i + 1;
                flag[j] = false;
            }
        }
    }

    //check them
    for(i = 1; i <= 6; i++){
        if(sz < 0){
            ans = false;
            break;
        }
    }
    for(i = 0; i < n; i++){
        if(flag[i]){
            ans = false;
            break;
        }
    }


    if(ans){
        cout << "YES" << endl;
        for(i = 0; i < n; i++){
            cout << mp2[v[i]] << "\n";
        }
    }
    else cout << "NO" << endl;


    #ifdef LOCAL
    memset(sz, 0, sizeof sz);
    memset(flag, false, sizeof flag);
    cout << endl;
    }
    #endif // LOCAL
    return 0;
}

  Thank you!

                                                                                                                                               ------from ProLights 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值