[队内测试Day10.10]贪心+模拟+BFS

听说今后会两天一考……
嘛,尽量把题目都整理下吧

T1

大意:

n种颜料,只能成套买,每套50ml;另有灰色颜料只可由3种不同颜料合成。给出每种颜料需要多少,求最少几套颜料可满足要求

正解:贪心,每次取最多的三种颜料合成

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 100 + 50;
int cnt,a[MAXN],n,x,m,tmp[MAXN],maxn;
bool cmp(int a,int b)
{
    return a > b;
}
int main()
{
    while(scanf("%d",&n) && n)
    {
        cnt = 1;maxn = 0;
        for(int i = 1;i <= n;i ++)
        {
            scanf("%d",&tmp[i]);
        }
        sort(tmp + 1,tmp + n + 1,cmp);
        cnt = tmp[1]/50 + 1;
        if(tmp[1]%50 == 0)cnt --;
        for(int i = 1;i <= n;i ++)
        {
            a[i] = cnt * 50 - tmp[i];
        }
        scanf("%d",&m);
        while(m)
        {
            if(!a[3])
            {
                for(int i = 1;i <= n;i ++)a[i] += 50;
                cnt ++;
            }
            else
            {
                a[1] --;
                a[2] --;
                a[3] --;
                m --;
                sort(a + 1,a + n + 1,cmp);
            }
        }
        printf("%d\n",cnt);
    }
    return 0;
}

打出来更像模拟……毕竟数据范围太小了……
考场上误以为满足电池的性质……二分答案……于是悲惨的挂了……

T2

大意:

X*Y的矩阵上分布n个敌人,给出每个敌人的坐标和出发点、到达点,求在离敌人最短距离最大化的前提下,起点至终点的最短距离

对于第二问,因为是曼哈顿距离所以在最小距离的限制下BFS就可以了
对于第一问:预处理出地图上每个点距敌人的最短距离
那复杂度不是n*X*Y的吗?
然而每个格子距敌人的最短距离仅会由离他最近的敌人确定……
再加上BFS神奇的宽度优先性质,最先搜到的距离一定是每个格子的最短距离……
然后二分答案,在每个距离限制下BFS一遍判断能否由起点到达终点

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
const int MAXN = 1000 + 50;
struct zt
{
    int x,y,step;
};
queue <zt> q;
int N,n,m,map[MAXN][MAXN],x,y,x0,y0,x1,y1;
int mu[] = {0,1,-1,0},
     mr[] = {1,0,0,-1};
void init()
{
    while(!q.empty())
    {
        zt u = q.front();
        q.pop();
        for(int i = 0;i < 4;i ++)
        {
            int xx = u.x + mu[i];
            int yy = u.y + mr[i];
            if(xx >= 0 && yy >= 0 && xx < n && yy < m && map[xx][yy] == -1)
                map[xx][yy] = map[u.x][u.y] + 1,q.push((zt){xx,yy});
        }
    }
}
bool vis[MAXN][MAXN];
int C(int x)
{
    if(x1 == x0 && y1 == y0)return 0;
    memset(vis,0,sizeof(vis));
    vis[x0][y0] = true;
    while(!q.empty())q.pop();
    q.push((zt){x0,y0});
    while(!q.empty())
    {
        zt u = q.front();
        q.pop();
        for(int i = 0;i < 4;i ++)
        {
            int xx = u.x + mu[i];
            int yy = u.y + mr[i];
            if(xx >= 0 && yy >= 0 && xx < n && yy < m && !vis[xx][yy] && map[xx][yy] >= x)
            {
                q.push((zt){xx,yy,u.step + 1});
                vis[xx][yy] = true;
                if(xx == x1 && yy == y1)
                {
                    return u.step + 1;
                }
            }
        }
    }
    return -1;
}
int step;
int main()
{
    freopen("escape.in","r",stdin);
    freopen("escape.out","w",stdout);
    scanf("%d%d%d",&N,&n,&m);
    scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
    memset(map,-1,sizeof(map));
    for(int i = 1;i <= N;i ++)
    {
        scanf("%d%d",&x,&y);
        q.push((zt){x,y});
        map[x][y] = 0;
    }
    init();
    int L = -1,R = map[x0][y0] + 1;
    while(R - L > 1)
    {
        int mid = L + R >> 1;
        int temp = C(mid);
        if(temp != -1)L = mid,step = temp;
        else R = mid;
    }
    printf("%d %d",max(0,L),step);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

一开始看错了题……以为是到每个敌人曼哈顿距离最大的点……
还很兴奋的写了半天二维前缀和……当然最后这题是弃了Orz
然后一听题解发现这题才最可做……

T3

poj1837

DP,没写正解
考场上打了个奇怪的gcd+爆搜然而跪了……

Tips:
考试策略还是有很大问题,下次争取先把暴力分都拿到……
要是继续考这分初赛都要跪
怎么办药丸药丸QAQ

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值