A

题解:

签到题,白色便宜就打白色,彩色便宜就打彩色

代码:

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

#define endl "\n"
#define ll long long

void solve(){
    ll a,b,x,y;
    if(x > y) b += a,a= 0;
    cout<<a*x + b*y<<endl;
}

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

B

题解:

贪心,每次让n变为能到达的最大的数字

如果是奇数就n/2 , 偶数就是 n/2-1

代码:

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

#define endl "\n"
#define ll long long

void solve(){
    ll n;cin>>n;
    int ans = 0;
    while(n){
        if(n&1) n = n/2;
        else n = n/2 - 1;
        ans ++;
    }
    cout<<ans<<endl;
}

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

C

题解:

将S能到达的地区标记为1,E能到达的地区标记为2,然后判定每个2的附近3行行列是否有1,有的话就可以直接贯穿

代码:

#include<iostream>
#include<bits/stdc++.h>
#include<set>
#include<map>
#include<queue>
using namespace std;

#define endl "\n"
#define ll long long

void solve() {
    int n, m; cin >> n >> m;
    vector<string> grid(n);
    for (auto& x : grid) cin >> x;

    queue<pair<int, int>> q;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (grid[i][j] == 'S') {
                q.push({ i,j });
            }
        }
    }
    auto msk1 = grid;
    int dx[4] = { -1,1,0,0 };
    int dy[4] = { 0,0,-1,1 };
    while (q.size()) {
        auto p = q.front(); q.pop();
        int x = p.first, y = p.second;
        msk1[x][y] = '1';
        for (int i = 0; i < 4; i++) {
            int tox = x + dx[i], toy = y + dy[i];
            if (tox < 0 || tox >= n || toy < 0 || toy >= m) continue;
            if (grid[tox][toy] == '#') continue;
            if (msk1[tox][toy] == '1') continue;
            msk1[tox][toy] = '1';
            q.push({ tox,toy });
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (grid[i][j] == 'E') {
                q.push({ i,j });
            }
        }
    }
    auto msk2 = grid;
    while (q.size()) {
        auto p = q.front(); q.pop();
        int x = p.first, y = p.second;
        msk2[x][y] = '2';
        for (int i = 0; i < 4; i++) {
            int tox = x + dx[i], toy = y + dy[i];
            if (tox < 0 || tox >= n || toy < 0 || toy >= m) continue;
            if (grid[tox][toy] == '#') continue;
            if (msk2[tox][toy] == '2') continue;
            msk2[tox][toy] = '2';
            q.push({ tox,toy });
        }
    }

    vector<int> h1(n, 0), z1(m, 0);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (msk1[i][j] == '1') {
                h1[i] = 1; z1[j] = 1;
            }
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (msk2[i][j] == '2') {
                for(int k = -1;k<=1;k++){
                    if(i + k >= 0 && i + k < n && h1[i+k]){
                        cout << "YES" << endl; return;
                    }
                    if(j + k >= 0 && j + k < n && z1[j+k]){
                        cout << "YES" << endl; return;
                    }
                }
            }
        }
    }
    cout << "NO" << endl;
}

signed main() {
    cin.tie(0); cout.tie(0);
    ios::sync_with_stdio(0);
    solve();
}

D

题解:

根据素数的稠密性,直接开一个长度为100n的数字,进行暴力剔除不满足的时间

代码:

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

#define endl "\n"
#define ll long long

void solve(){
    int n;cin>>n;
    vector<int> a(n);
    for(int&x:a) cin>>x;
    int m = 100*n + 10;
    vector<int> dp(m,0);
    set<int> se(a.begin(),a.end());
    for(int x:se){
        for(int j = x; j<m;j+=x){
            dp[j] = 1;
        }
    }
    for(int i = 2;i<m;i++){
        if(dp[i] == 0){
            cout<<i<<endl;return;
        }
    }
}

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

E

题解:

将能连续倒塌的多米诺骨牌看作一个块,将每个块取出来,贪心取m个就行

代码:

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

#define endl "\n"
#define ll long long

void solve(){
    ll n,m;cin>>n>>m;
    vector<pair<ll,ll>> vp(n);
    for(ll i =0;i<n;i++) cin>>vp[i].first;
    for(ll i =0;i<n;i++) cin>>vp[i].second;
    for(ll i =0;i<n;i++) swap(vp[i].first , vp[i].second);
    sort(vp.begin(),vp.end());
    vector<ll> k;
    ll p = 0;
    while(p < n){
        ll rp = vp[p].first + vp[p].second;
        ll sz = 1;
        while(p + 1 < n && rp >= vp[p+1].first){
            p ++;sz ++;
            rp = max(rp , vp[p].first + vp[p].second);
        }
        p++;
        k.push_back(sz);
    }
    sort(k.begin(),k.end());
    reverse(k.begin(),k.end());
    ll ans = 0;
    for(ll i =0 ;i<k.size() && i < m;i++){
        ans += k[i];
    }
    cout<<ans<<endl;
}

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

F

题解:

对于每两个相邻的墙,我们能获取2*dis的时间,那么一共有2 * m的不同时间,直接进行完全背包即可

代码:

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

#define endl "\n"

void solve(){
    int n,m,t;cin>>n>>m>>t;
    vector<int> a(m);
    for(int&x:a) cin>>x;
    if(n>t){
        cout<<0<<endl;return;
    }
    sort(a.begin(),a.end());
    set<int> b;
    for(int i=1;i<m;i++) b.insert(a[i] - a[i-1]);
    vector<int> w;
    for(int x:b) w.push_back(x);
    vector<int> dp(t+1,0);
    dp[n] = 1;
    for(int x:w){
        for(int j =0;j<=t;j++){
            if(j + 2*x > t) continue;
            if(dp[j]){
                dp[j + 2*x ] |= dp[j];
            }
        }
    }
    for(int i = t;i>=0;i--){
        if(dp[i]){
            cout<<i<<endl;return;
        }
    }
}

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

G

题解:

暴力维护每个时间点的各种🐟的状态,然后从x暴力跳最大能吃的,因为每次x加倍,所有跳lgw次,这个用set+离散化+树状数组维护区间sum就行

代码

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

//坐标从0开始直接用的树状数组
#define ll long long
template <typename T>
class Fenwick
{
private:
    ll n;
    vector<T> c;
    ll lowbits(ll x){
        return (-x) & x;
    }
    ll pre_sum(ll i){
        ll re = 0;
        for (; i > 0; i -= lowbits(i))
            re += c[i];
        return re;
    }
public:
    explicit Fenwick<T>(vector<T> v){
        this->n = v.size();
        this->c = vector<T>(n+1,0);
        for(ll i=0;i<n;i++)
            add(i,v[i]);
    };
    void add(ll i, ll val){
        ++i;
        for (;i<=n; i += lowbits(i))
            c[i] += val;
    }
    ll range_sum(ll i,ll j){
        ++i;++j;
        return pre_sum(j) - pre_sum(i - 1);
    }
};
void solve(){
    ll n,x;cin>>n>>x;
    vector<vector<ll>> vp;
    vector<ll> b;
    for(ll i =0 ;i<n;i++){
        ll l,r,y;cin>>l>>r>>y;
        vp.push_back({l,y,0});
        vp.push_back({r,y,1});
        b.push_back(y);
    }
    sort(b.begin(),b.end());
    map<ll,ll> mp;
    // 离散化
    for(ll i =0 ;i<n;i++) mp[b[i]] = i;
    Fenwick<ll> fw(vector<ll>(n,0));

    sort(vp.begin(),vp.end());
    multiset<ll> se;
    ll ans = 0;
    for(ll i = 0;i<2*n;){
        ll p1 = vp[i][0] , y = vp[i][1] , op = vp[i][2];
        while(i<2*n && vp[i][0] == p1){
            ll ny = vp[i][1] , nop = vp[i][2];
            if(nop==0){
                se.insert(ny);
                fw.add(mp[ny],ny);
            }else{
                se.erase(se.find(ny));
                fw.add(mp[ny],-ny);
            }
            i++;
        }
        // 找答案
        ll tval = x;
        ll pos = 0;
        while(1){
            auto it = se.lower_bound(tval);
            if(it==se.end()){
                tval += fw.range_sum(pos,n-1);break;
            }
            if(*it > tval){
                if(it==se.begin()) break;
                it = prev(it);
            } 
            ll pr = mp[*it];
            if(pr < pos) break;
            tval += fw.range_sum(pos , pr);
            pos = pr + 1;
        }
        ans = max(ans, tval);
    }
    cout<<ans<<endl;
}

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

****************************** alt