2025 Wuhan University of Technology Programming Contest

2025 Wuhan University of Technology Programming Contest

一、L题

签到题,重要是要读懂题,合成的话单个物品也可以合成其他的。然后有个小坑就是题目中n可以等于m,但也是至少要加一次EMC。(导致作者wa一次)

#include <iostream>
using namespace std;
int main() {
    int n,m;
    cin>>n>>m;
    cout<<max(1,n-m)<<'\n';
    return 0;
}

二、k题

排序,注意题目中的顺序是可变的。那么就简单多了。

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+5;

void solve() {
    vector<int>a(N,0);
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    sort(a.begin(), a.begin()+n);
    int presum=0,ans=0;
    for (int i = 0; i < n; i++) {
        if (presum <= a[i]) {
            ans++;
            presum+=a[i];
        }
    }
    cout << ans << '\n';

}
int main() {
    ios_base::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
    int T;
    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}

强化变种一下:如果不可变顺序的话该怎么写呢 -------单调栈

void solve() {
    vector<int>a(N,0);
    stack<int> s;
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    int presum=0;
    for (int i = 1; i <= n; i++) {
        while (!s.empty()&&a[s.top()]>a[i]) {
            if (presum - a[s.top()]<=a[i]) {
                presum -= a[s.top()];
                s.pop();
            }else {
                break;
            }
        }
        if (presum<=a[i]) {
            s.push(i);
            presum+=a[i];
        }
    }
    cout<<s.size()<<'\n';
}

三、A题

x表示星元自动机,y为辅助
a,b,n为题目中的意思
数学公式表达化简,即可。
注意事项:特殊值需要判断,如b= =1,n==0。
在这里插入图片描述

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

void solve() {
    int n,a,b;
    cin>>n>>a>>b;
    if (b==0) {
        if (a > 1) {
            cout<<a * n<<'\n';
        }
        else {
            cout<<n<<'\n';
        }
        return;
    }
    if (n == 1) {
        cout<<max(a,1ll)<<'\n';
        return;
    }
    double t = (double)(a + b * n - 1)/(2 * b);
    int tp = static_cast<int>(t + 0.5);
    tp = min(tp,n);//万一对称轴在区间外,就是n。
    int ans = (a + b * (n - tp)) * tp + (n - tp);
    cout<<ans<<'\n';
}
signed main() {
    ios_base::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
    int T;
    cin>>T;
    while(T--) {
        solve();
    }
    return 0;
}

四、H题

主要考察观察能力和逆元求解,需要用到快速幂。
直接说结论:
1. 当 n 为偶数时 ( 2 n − 1 ) (2^{n}-1) (2n1) / 3 * 2
节点数的2/3 就是答案;
2. 当 n 为偶数时 ( 2 n − 1 − 1 ) (2^{n}-1 -1) (2n11) / 3 * 2
节点数的-1(减去根节点) × 2/3

注意计算除法时要用逆元来算,不能直接除

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
const ll mod = 998244353;
ll qmi(ll a,ll b) {
    ll ans = 1;
    while (b) {
        if (b&1) {
            ans = ans*a % mod;
        }
        a = a * a % mod;
        b>>=1;
    }
    return ans;
}//快速幂
void solve() {
    int n;
    cin >> n;
    ll res = qmi(2,n)-1;
    ll niyuan3 = qmi(3,mod-2);//求三的逆元,费马小定理
    ll ans =0;
    if (n%2==0) {
        ans = res * niyuan3 * 2 % mod;
    }else {
        ans = ((res - 1) * niyuan3 * 2 % mod + 1) % mod;
    }
    cout << ans << '\n';
}
signed main() {
    ios_base::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL);
    int T;
    cin >> T;
    while(T--) {
        solve();
    }
    return 0;
}

五、j题

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
bool f(int x){
    for(int i=2;i<=sqrt(x);i++){
        if(x%i==0){
            return false;
        }
    }
    return true;
}
int main()
{
    int n;
    cin>>n;
    vector<int>ans(n);
    int cnt=1;
    for(int i=n+1;i<100000;i++){
        if(f(i)){
            cout<<cnt*i<<" ";
            cnt++;
        }
        if(cnt>n){
            break;
        }
    }
}

六、C题

前缀和 + 多源bfs
1.输入处理:读取网格尺寸和矿场信息。
2.差分数组初始化:标记矿场覆盖区域。
3.多源BFS:计算每个非矿场格子到最近矿场的曼哈顿距离。
4.结果计算:遍历所有非矿场格子,计算最大支撑距离。
5.输出结果:根据计算结果输出最大支撑距离或-1。

#include<bits/stdc++.h>
using namespace std;
const int dx[4] = {0, 0, 1, -1};
const int dy[4] = {1, -1, 0, 0};

int main() {
    int n, m, k;
    cin >> n >> m >> k;

    vector<vector<int>> diff(n + 2, vector<int>(m + 2, 0));//前缀和数组
    vector<vector<bool>> vis(n + 1, vector<bool>(m + 1, false));

    for (int idx = 0; idx < k; idx++) {
        int xx, yy, dis;
        cin >> xx >> yy >> dis;
        int x_low = max(1, xx - dis);
        int x_high = min(n, xx + dis);
        int y_low = max(1, yy - dis);
        int y_high = min(m, yy + dis);

        diff[x_low][y_low] += 1;
        if (y_high + 1 <= m) diff[x_low][y_high + 1] -= 1;
        if (x_high + 1 <= n) diff[x_high + 1][y_low] -= 1;
        if (x_high + 1 <= n && y_high + 1 <= m) diff[x_high + 1][y_high + 1] += 1;
    }

    for (int i=1;i<=n;i++) {
        for (int j=1;j<=m;j++) {
            diff[i][j]+=diff[i-1][j]+diff[i][j-1]-diff[i-1][j-1];
        }
    }//前缀和
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (diff[i][j] > 0) {
                vis[i][j] = true;//》0的标记为矿场
            }
        }
    }
    //多源bfs
    vector<vector<int>> dist(n + 1, vector<int>(m + 1, -1));
    queue<pair<int, int>> q;

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (vis[i][j]) {
                dist[i][j] = 0;
                q.push({i, j});
            }
        }
    }

    while (!q.empty()) {//计算的是每一个空地到矿场的最短曼哈顿距离
        auto [x, y] = q.front();
        q.pop();
        for (int dir = 0; dir < 4; dir++) {
            int nx = x + dx[dir];
            int ny = y + dy[dir];
            if (nx >= 1 && nx <= n && ny >= 1 && ny <= m && dist[nx][ny] == -1) {
                dist[nx][ny] = dist[x][y] + 1;
                q.push({nx, ny});
            }
        }
    }

    int ans = -1;
    for (int x = 1; x <= n; x++) {
        for (int y = 1; y <= m; y++) {
            int d_safe = dist[x][y] - 1;
            if (d_safe > ans) ans = d_safe;
        }
    }

    if (ans == -1) {
        cout << -1 << endl;
    } else {
        cout << ans << endl;
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值