2022“杭电杯”中国大学生算法设计超级联赛(1)题解报告

本文介绍了多个算法问题的解决方案,包括基于概率的期望计算、最短路径策略以及图论在不同场景的应用。具体涉及二分法去除最大或最小值的期望计算、有向图中消除障碍物的最短路径、数字处理策略以及构建最优激光路径和背包问题的解法。同时,文章涵盖了迪杰斯特拉算法的变体和曼哈顿距离的中位数问题。

 Problem K. Random

题目大意:

给你N个0~1内的随机数,M次操作,每次操作二分之一的概率去掉所有数中的最小值或最大值,问最后留下来的数字的期望。

题解:

显而易见答案是 (n - m) / 2 ,求出2的逆元即可。

代码:

#include<iostream>
#define int long long
using namespace std;

const int mod = 1e9 + 7;

int n, m;
int tmp = (mod + 1) / 2;

void solve(){
    cin >> n >> m;
    cout << (n - m) * tmp % mod << '\n';
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--){
        solve();
    }
}

Problem B. Dragon slayer

题目大意:

给定n * m的区域,英雄初始在一个给定的格子内,他要前往巨龙的巢穴,沿途有K堵墙(墙为格子边缘连成的直线),问英雄前往巢穴至少要摧毁多少堵墙。

题解:

墙的数量K最多只给到15,爆搜或者状压都能比较轻松的通过。

代码:

#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#define INF 0x3f3f3f3f3f3f3f3f
#define int long long
using namespace std;

const int N = 15 + 10;

int n, m, k;
int xs, ys, xt, yt;
int mp[20][20], lw[20][20], dw[20][20];

struct edge{
    int x[2], y[2];
}e[20];

bool dfs(int x, int y){
    mp[x][y] = 1;
    if(x == xt && y == yt){
        return true;
    }
    bool flag = false;
    if(x >= 1 && lw[x][y] == 0 && mp[x - 1][y] == 0){
        flag |= dfs(x - 1, y);
    }
    if(x + 1 < n && lw[x + 1][y] == 0 && mp[x + 1][y] == 0){
        flag |= dfs(x + 1, y);
    }
    if(y >= 1 && dw[x][y] == 0 && mp[x][y - 1] == 0){
        flag |= dfs(x, y - 1);
    }
    if(y + 1 < m && dw[x][y + 1] == 0 && mp[x][y + 1] == 0){
        flag |= dfs(x, y + 1);
    }
    return flag;
}

bool check(int s){
    memset(mp, 0, sizeof(mp));
    memset(lw, 0, sizeof(lw));
    memset(dw, 0, sizeof(dw));
    for(int i = 0; i < k; i++){
        if((s & (1 << i)) == 0){
            if(e[i].x[0] == e[i].x[1]){
                for(int j = e[i].y[0]; j < e[i].y[1]; j ++){
                    lw[e[i].x[0]][j] = 1;
                }
            }
            else{
                for(int j = e[i].x[0]; j < e[i].x[1]; j ++){
                    dw[j][e[i].y[0]] = 1;
                }
            }
        }
    }
    return dfs(xs, ys);
}

int popcount(int x){
    int cnt = 0;
    while(x){
        if(x & 1) cnt ++;
        x >>= 1;
    }
    return cnt;
}

int f[(1 << 15) + 10];

void solve(){
    cin >> n >> m >> k >> xs >> ys >> xt >> yt;
    for(int i = 0; i < k; i++){
        cin >> e[i].x[0] >> e[i].y[0] >> e[i].x[1] >> e[i].y[1];
        if(e[i].x[0] == e[i].x[1] && e[i].y[0] > e[i].y[1]){
            swap(e
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值