CSU-2101: Bake Off

2101: Bake Off

Submit Page      Summary      Time Limit: 8 Sec       Memory Limit: 128 Mb       Submitted: 73       Solved: 19    

Description

Davy decided to start a weekend market stall where he sells his famous cakes. For the first market stall, Davy decided to bake n cakes. Each cake is described by its deliciousness and the flavours it contains, which is a (possibly empty) subset of the flavours {caramel, cherry, chocolate, cinnamon, coconut, cookies}. Because of Davy’s skill in baking, he has a line of m customers when he opens his stall who wish to buy a cake. Davy will serve them in the order they are lined up. Each customer has a required subset of flavours they would like in their cake, but are happy to receive additional flavours in their cake. Davy will give each customer the most delicious cake left that contains at least the flavours that the customer has asked for. You should help Davy determine which cake to sell to each customer (or if there is no cake that satisfies that customer’s requirements, in which case, they buy nothing).

Input

The first line contains two integers n (1 ≤ n ≤ 300 000), which is the number of cakes, and m (1 ≤ m ≤ 100 000), which is the number of customers. The next 6 lines describe the flavours contained in the cakes. The first of these lines contains a string of length n, which describes if caramel is in each cake. This string will contain a 1 in the ith position if cake i contains caramel and 0 otherwise. The second through sixth of these lines will describe cherry, chocolate, cinnamon, coconut and cookies, respectively, in the same format. The cakes are numbered from left to right, starting with cake 1 on the left. No two cakes have the same deliciousness and are sorted by their deliciousness, with cake 1 being the least delicious and cake n being the most delicious. The next 6 lines describe the flavours requested by the customers. The first of these lines contains a string of length m, which describes if each customer has requested caramel in their cake. This string will contain a 1 in the ith position if customer i requested caramel and 0 otherwise. The second through sixth of these lines will describe cherry, chocolate, cinnamon, coconut and cookies, respectively, in the same format.

Output

Display the number of the cake purchased by each customer in the order that they are requested. If a customer does not purchase a cake, display -1 for them instead.

Sample Input

4 2
0001
1111
0001
1111
0001
1111
01
11
01
11
01
11

3 4
000
000
000
010
101
110
0000
0000
0000
0010
1000
0100

Sample Output

4 -1

3 2 -1 1

Hint

Source

South Pacific Divisionals

题意:有n块蛋糕,每块蛋糕由6种调料的任意排列组成,输入越右边的蛋糕越美味。有m个人买蛋糕,给定m个人要求蛋糕上必须要有的调料(可以多),每次给满足条件里最美味的蛋糕,如果不存在输入-1否则输出是哪块蛋糕

题解:一共只有6种调料,故只有2^6 = 64种可能。对于每种可能,建立一个数组放置存在的位置(从左往右放)每次来一位顾客,就对于所有满足情况(用dfs求全排列)找最右边的(即数组最后的那个元素)

AC代码

#include <iostream>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>
#include <stdio.h>

using namespace std;

typedef long long ll;

const int maxn = 77, max1 = 3e5 + 10;
string c;
vector<int> s[maxn];
char a[6][max1];
int bbb, ccc;

struct node{
    string x;
    int num;
    node (string x1, int num1):x(x1), num(num1){}
};

bool cmp(node a1, node a2){
    return a1.num < a2.num;
}

int get_int(string a1){
    int ans = 0;
    for(int i = 0; i < a1.length(); i++)
        ans = ans * 2 + (a1[i] - '0');
    return ans;
}

void dfs(string b, int nn, int num){
    if(num == nn){
        string c2 = c;
        int cc = 0, c1;
        for(int i = 0; i < c.length(); i++){
            if(c[i] == '0'){
                c[i] = b[cc++];
            }
        }
        c1 = get_int(c);
        if(s[c1].size() != 0){
            if(bbb < s[c1][s[c1].size() - 1]){
                bbb = s[c1][s[c1].size() - 1];
                ccc = c1;
            }
        }
        c = c2;
        return;
    }
    dfs(b + '1', nn, num + 1);
    dfs(b + '0', nn, num + 1);
}

int main(){
    int n, m;
    while(scanf("%d %d", &n, &m) != EOF){
    	for(int i = 0; i < 6; i++){
    		scanf("%s", a[i]);
		}
		for(int i = 0; i < maxn; i++)
            s[i].clear();
   		for(int i = 0; i < n; i++){
            int num = 0;
            for(int j = 0; j < 6; j++){
                num = num * 2 + (a[j][i] - '0');
            }
            s[num].push_back(i);
   		}
   		for(int i = 0; i < 6; i++)
            scanf("%s", a[i]);
        for(int i = 0; i < m; i++){
            int num = 0;
            int nn = 0;
            c = "";
            for(int j = 0; j < 6; j++){
                c += a[j][i];
                num = num * 2 + (a[j][i] - '0');
                if(a[j][i] == '0')
                    nn += 1;
            }
            bbb = -1;
            dfs("", nn, 0);
            if(bbb == -1){
                printf("-1");
            }
            else{
                s[ccc].erase(s[ccc].end() - 1);
                printf("%d", bbb + 1);
            }
            if(i != m - 1)
                printf(" ");
        }
	}
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值