Codeforces Round #413 (Div. 2)

链接: http://codeforces.com/contest/799

A

大意:给定需要烤的蛋糕总数、每个烤箱一次可同时烤的面包个数、每个烤箱烤一次所需要的时间、第二个烤箱加入的时间。问如果在该时间加入烤箱,能否更快的将所有蛋糕拷完。

思路:顺着题意想就行,如果蛋糕总数小于烤箱容量,直接输出“No”。如果在烤最后一组蛋糕前,第二个烤箱还没有加入,也输出”No”。其余情况都是”Yes”。

代码如下:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <stdio.h>
using namespace std;
int main(){

    int n, t, k, d;
    scanf("%d%d%d%d", &n, &t, &k, &d);
    int num = 0; //看一共要分多少次烤蛋糕
    if (n%k == 0)   num = n / k;
    else   num = (n / k) + 1;
    if (n <= k) printf("No\n");
    else if ((num - 1)*t <= d) printf("No\n");
    else printf("Yes\n");

    return 0;
}

B

大意:有m个T-shirt,分别有价格、前面颜色、背面颜色三个属性。有n个顾客,每个顾客依次选择喜欢的颜色,然后依次给出颜色匹配的最低价格的T-shirt。

思路:

开始我是想用三个优先队列,分别对应不同种颜色的价格,但是这样会有重复的情况,所以需要往优先队列中传结构体。
我就想那样还有点麻烦,直接用最暴力的方法,每个T-shirt作为一个结构体,然后每次都遍历。这样的方法能通过几个样例,但是后面的测试样例会超时,所以还是重新选用优先队列吧。

下面是暴力的方法代码:(仅通过了部分样例,剩下的超时)

#include <iostream>
#include <cstring>
#include <cstdio>
#include <stdio.h>
#include <algorithm>
using namespace std;
struct shirt{//结构体,包括价格,前后面颜色,是否已被购买
    long long price;
    int front;
    int back;
    int flag = 1;
};
shirt tshirt[200005];
int main(){
    int m, n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++){
        scanf("%I64d", &tshirt[i].price);
    }
    for (int i = 0; i < n; i++){
        scanf("%d", &tshirt[i].front);
    }
    for (int i = 0; i < n; i++){
        scanf("%d", &tshirt[i].back);
    }
    scanf("%d", &m);
    int color;//表示目前顾客喜欢的颜色
    int num; //保留满足要求的最小Tshirt的序号
    for (int i = 0; i < m; i++){
        num = -1;
        scanf("%d", &color);
        for (int j = 0; j < n; j++){
            if (tshirt[j].flag == 0)  continue;
            if (num == -1 && tshirt[j].back == color)  {
                num = j;   continue;
            }
            if (tshirt[j].back == color && tshirt[j].price < tshirt[num].price){
                num = j;
            }
            if (num == -1 && tshirt[j].front == color)  {
                num = j;  continue;
            }
            if (tshirt[j].front == color && tshirt[j].price < tshirt[num].price){
                num = j;
            }
        }
        if (num != -1) tshirt[num].flag = 0;//不要忘了标记一下
        if (num == -1)  printf("-1 ");
        else
            printf("%I64d ", tshirt[num].price);
        }

    printf("\n");

    return 0;
}

将原来的方法改为使用优先队列后,就通过了所有样例。
需要注意的是,三个优先队列都需要存储价格和id信息,从而标记哪些T-shirt被售出。而且,需要重载运算符,才能实现对优先队列的排序。
AC代码如下:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <stdio.h>
#include <algorithm>
#include <queue>
using namespace std;
struct shirt{
    long long price;
    int front;
    int back;
    int flag = 1;
};
shirt tshirt[200005];
struct id_price{
    int id;
    long long price;
    id_price(int i, long long p){
        id = i;
        price = p;
    }
};
bool operator < (id_price a, id_price b){  //在这里,将结构体作为优先队列的元素后,需要重载运算符
    if (a.price > b.price) return true;
    else return false;
}
priority_queue<id_price> q1, q2, q3; //分别表示含有三种颜色的T-shirt的id
int main(){
    int m, n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++){
        scanf("%I64d", &tshirt[i].price);
    }
    for (int i = 0; i < n; i++){
        scanf("%d", &tshirt[i].front);
    }
    for (int i = 0; i < n; i++){
        scanf("%d", &tshirt[i].back);
    }
    for (int i = 0; i < n; i++){
        if (tshirt[i].front == 1 || tshirt[i].back == 1)  q1.push(id_price(i, tshirt[i].price)); 
        if (tshirt[i].front == 2 || tshirt[i].back == 2)  q2.push(id_price(i, tshirt[i].price));
        if (tshirt[i].front == 3 || tshirt[i].back == 3)  q3.push(id_price(i, tshirt[i].price));
    }
    scanf("%d", &m);
    int color;
    for (int i = 0; i < m; i++){
        scanf("%d", &color);
        if (color == 1) {
            while (!q1.empty() && tshirt[q1.top().id].price == -1) q1.pop(); //之前在这里出错了,应该先判断是否为空,再判断价格是否为-1
            if (q1.empty())  printf("-1 ");
            else   {
                printf("%I64d ", q1.top().price);
                tshirt[q1.top().id].price = -1; //如果已经买过了,就将价格标为-1
                q1.pop();
            }
        }
        else if (color == 2){
            while (!q2.empty() && tshirt[q2.top().id].price == -1) q2.pop();
            if (q2.empty())  printf("-1 ");
            else   {
                printf("%I64d ", q2.top().price);
                tshirt[q2.top().id].price = -1;
                q2.pop();
            }
        }
        else {
            while (!q3.empty() && tshirt[q3.top().id].price == -1) q3.pop();
            if (q3.empty())  printf("-1 ");
            else   {
                printf("%I64d ", q3.top().price);
                tshirt[q3.top().id].price = -1;
                q3.pop();
            }
        }
    }
    printf("\n");
    return 0;
}

C

题意:有n个喷泉,分别有beauty和cost和购买方式三种属性。现在有个人有一定数量的coins和diamonds。这个人用这些coins和diamonds购买两个喷泉,求所能购买的最大beauty。
思路:首先比较明显的是,要分三种情况,一种是用coins买一个,用diamonds买一个,这种情况比较简单。第二种是两个都用coins买。第三种是两个都用diamonds买。后两种情况都需要考虑复杂度的问题。
我还不了解线段树,就先放在这里,以后再做。
两个参考链接:
http://blog.youkuaiyun.com/OIljt12138/article/details/72997546
http://www.cnblogs.com/EDGsheryl/p/6865151.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值