牛客小白月赛60

比赛地址

A. 小竹与妈妈

题意:

妈妈的年龄是小竹的 a 倍多 b,已知妈妈年龄为 x ,求小竹年龄

思路:

签到题,小竹年龄 = ( x - b ) / a

AC代码:

#include <bits/stdc++.h>
using namespace std;
 
#define x first
#define y second
#define int long long
#define div cout << "--------------------------" << endl
 
const int N = 1e5 + 5;
typedef pair<int, int> PII;
 
int n, m;
int a[N];
 
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
     
    int a, b, c;
    cin >> a >> b >> c;
     
    cout << (c - b) / a << endl;
     
    return 0;
}

B. 走丢的小竹

题意:

n 个出口连着 m 个房间,已知有房间 k 有坏人,求有多少个出口能走

思路:

用 cnt 数组表示通向每个房间的的出口数,能走的出口数 = 总出口数 - 通向房间 k 的出口数n - cnt[ k ]

AC代码:

#include <bits/stdc++.h>
using namespace std;

// #define x first
// #define y second
#define int long long
#define div cout << "--------------------------" << endl

const int N = 1e5 + 5;
typedef pair<int, int> PII;

int a[N];
int b[N];

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    int n, m, q;
    cin >> n >> m >> q;
    
    for (int i = 1; i <= n; i ++)
    {
        int t;
        cin >> t;
        a[t] ++;            // 通往t房间的出口个数
    }
    
    while (q --)
    {
        int x;
        cin >> x;
        
        cout << n - a[x] << endl;
    }
    
    return 0;
}

C. 小竹关禁闭

题意:

n 个长度为 ai 物品选择若干个制作成绳子,要使得绳子总长度最长,限制:选了第 i 个物品后,其右边 k 个物品皆不能使用

思路:

DP
请添加图片描述

AC代码:

#include <bits/stdc++.h>
using namespace std;

// #define x first
// #define y second
#define int long long
#define div cout << "--------------------------" << endl

const int N = 1e5 + 5;
typedef pair<int, int> PII;

int a[N];
int f[N];

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    int n, k;
    cin >> n >> k;
    
    for (int i = 1; i <= n; i ++)   cin >> a[i];
    
    f[n] = a[n];
    for (int i = n - 1; i >= 1; i --)
        f[i] = max(f[i + k + 1] + a[i], f[i + 1]);
    
    cout << f[1] << endl;

    return 0;
}

D.游戏购买!

题意:

n x m 的网格,要从起点先经过 特定点(可能不唯一) 再从特定点走向终点,求路径最小值

思路:

两遍 BFS
第一遍 BFS 求终点到所有点的路径最小值(必定包含到特定点的最小值),保存在 dist2[ N ]
第二遍 BFS 求起点到所有特定点的路径最小值为 dist1[ N ],再对所有的 dist1[ k ] + dist2[ k ] 求最小值

AC代码:

#include <bits/stdc++.h>
using namespace std;

#define x first
#define y second
#define int long long
#define div cout << "--------------------------" << endl

const int N = 2000 + 5;
typedef pair<int, int> PII;

int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};

int n, m, t;             // t 是刺激度
int x1, Y, x2, y2;

int g[N][N];
int dist[N][N];
int dist2[N][N];


void bfs2(PII start)    // 从 start 到 end 的距离
{   
    
    queue<PII> q;
    
    memset(dist2, -1, sizeof dist2);      // 初始化
    
    q.push(start);  // 起点入队
    dist2[start.x][start.y] = 0;     // 到起点距离为 0
    
    while (!q.empty())
    {
        auto item = q.front();     // 取队头
        q.pop();    // 弹出队头
        
        for (int i = 0; i < 4; i ++)    // 扩展队头
        {
            int x = item.x + dx[i], y = item.y + dy[i];   //  下一步
            if (x < 1 || x > n || y < 1 || y > m || g[x][y] == -1)    continue;   //  出界 或者 墙
            if (dist2[x][y] != -1)   continue;   // 该点走过
            
            dist2[x][y] = dist2[item.x][item.y] + 1;    // 更新距离
            
            q.push({x, y});   // 新点入队
        }
    }
    
}

int bfs(PII start)
{
    queue<PII> q;
    memset(dist, -1, sizeof dist);      // 初始化
    
    q.push(start);      // 起点入队
    dist[start.x][start.y] = 0;
    
    int waY = 10000;
    while (!q.empty())
    {
        auto item = q.front();      // 取队头弹出
        q.pop();               
        
        for (int i = 0; i < 4; i ++)    // 拓展队头
        {
            int x = item.x + dx[i], y = item.y + dy[i];   //  下一步
            if (x < 1 || x > n || y < 1 || y > m || g[x][y] == -1)    continue;   //  出界 或者 墙
            if (dist[x][y] != -1)   continue;   // 该点走过
            
            dist[x][y] = dist[item.x][item.y] + 1;

            if (g[x][y] > t)    // 当前是刺激点
            {   
                int now = dist[x][y];   // 从起点到当前刺激点距离为 now
                
                // cout << "从起点到当前刺激点距离为:" << now << endl;
                // cout << "当前刺激点为:" << x << ' ' << y << endl;
                
                PII start2 = {x, y};
                int way2 = dist2[x][y];   // 从当前终点到当前刺激点的路
                // cout << "当前刺激点到终点距离为:" << way2 << endl;
                if (way2 == -1)  continue;      // 如果从当前刺激点无法到达终点
                else waY = min(waY, way2 + now);
            }
            
            q.push({x, y});             // 新点入队
        }
    }
    
    if (waY == 10000)  return -1;
    else return waY;
}


signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    cin >> n >> m >> t;
    cin >> x1 >> Y >> x2 >> y2;
    
    PII start = {x1, Y};
    PII end = {x2, y2};
    
    for (int i = 1; i <= n; i ++)
        for (int j = 1; j <= m; j ++)
            cin >> g[i][j];
               
    bfs2(end);
    cout << bfs(start) << endl;   
    return 0;
}

E.寻找小竹!

题意:

思路:

AC代码:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值