前言:

当天晚上小白有事没有打,赛后模拟了一下,A了三题,无Wa,E题绷了半天出不来,估计是能上分(应该?)

赛后补补题

花了点时间把D和E补完了(累~~) -----2024.9.10


1.ACM中的A题

直接枚举每条边乘2的结果判断即可

估计要开longlong ?? (要的)

LL san(LL a,LL b,LL c){
    if(a+b<=c || a-b>=c || b+c<=a || b-c>=a || a+c<=b || a-c>=b){
        return 0;
    }
    else{
        return 1;
    }
} 
void solve()
{
    LL a,b,c,a1,b1,c1;
    cin>>a>>b>>c;
    a1 = a ,b1 = b,c1 = c;
    a1*=2;
    if(san(a1,b1,c1)==1){
        cout<<"Yes";
        return;
    }
    a1 = a;
    b1*=2;
    if(san(a1,b1,c1)==1){
        cout<<"Yes";
        return;
    }
    b1 = b;
    c1*=2;
    if(san(a1,b1,c1)==1){
        cout<<"Yes";
        return;
    }
    cout<<"No";
}

2. ACM中的C题

特判一下n==1的情况,然后分奇数和偶数计算,奇数就要多花一次机会交换

void solve()
{
   int n;
   cin>>n;
   vector<int> a(n);
   for(int i=1;i<=n;i++) cin>>a[i];
    if(n==1){
        cout<<-1;
    }
    else{
        if(n%2==0){
            cout<<n/2;
        }
        else{
            cout<<n/2+1;
        }
    }
}

3. ACM中的M题

同样道理,先特判n==1 ,然后对于同一类型若只有一个,也是不行的,考虑用Map存储计算答案

void solve()
{
   int n;
   cin>>n;
   vector<int> a(n+1,0),b(n+1,0);
   for(int i=1;i<=n;i++) cin>>a[i];
    map<LL,LL> q;
    for(int i=1;i<=n;i++){
        cin>>b[i];
        q[b[i]]++;
    }
    if(n==1){
        cout<<-1;
    }
    else{
        vector<int> dp;
        for(auto &i:q){
            if(i.second==1){
                cout<<-1;
                return;
            }
            else{
                dp.push_back(i.second);
            }
        }
        LL ans = 0;
        for(int i = 0;i<dp.size();i++){
            if(dp[i]%2==0){
                ans+=(dp[i]/2);
            }
            else{
                ans+=(dp[i]/2+1);
            }
        }
        cout<<ans;
    }
}

4. ACM中的AC题

思考点:选定一个点后,走入传送门结束,另一个点一定可以沿着刚刚的路径走回去(但不一定是最大,而且保证走之前没被堵死)

1.使用dis来存储先进的点,d来存储后进的点位

2.在dis中尽可能铺满所有可以走的点,判断另一个方向不会被堵死,实际操作就是一个点进完了后,另一个点 在对称点,再计算一次由附近最近的@点进行收容,一次向外括,一次向内

#include <bits/stdc++.h>
using namespace std;
using LL =long long;
const int N = 2e3+5;
int n,m,x,y;
int dis[N][N],d[N][N];
char a[N][N];
int dx[4] = {1,0,-1,0};
int dy[4] = {0,-1,0,1};
bool ckn(int x,int y){
    return x>=1 && x<=n && y>=1 && y<=m && a[x][y]!='#';
}
void solve(){
    cin>>n>>m>>x>>y;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>a[i][j];
            dis[i][j] = 1e9;
            d[i][j] = 1e9;
        }
    }
    queue<pair<int,int> > q;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(a[i][j]=='@'){
                d[i][j] = 0;
                q.push({i,j});
            }
        }
    }
    while(!q.empty()){
        auto op = q.front();
        int cx = op.first;
        int cy = op.second;
        q.pop();
        for(int i=0;i<4;i++){
            int nx = cx + dx[i];
            int ny = cy + dy[i];
            if(ckn(nx,ny) && d[nx][ny]>d[cx][cy]+1){
                d[nx][ny] = d[cx][cy] + 1;
                q.push({nx,ny});
            }
        }
    }
    dis[x][y]=0;
    q.push({x,y});
    while(!q.empty()){
        auto op = q.front();
        int cx = op.first;
        int cy = op.second;
        q.pop();
        for(int i=0;i<4;i++){
            int nx = cx + dx[i];
            int ny = cy + dy[i];
            if(ckn(nx,ny) && ckn(2*x-nx,2*y-ny) && dis[nx][ny]>dis[cx][cy]+1){
                dis[nx][ny] = dis[cx][cy] + 1;
                q.push({nx,ny});
            }
        }
    }
    int ans = 2e9;
     for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(a[i][j]=='@'){
                ans = min(ans , dis[i][j]+d[2*x-i][2*y-j]);
            }
        }
    }
    if(ans>=1e9){
        cout<<-1;
    }
    else{
        cout<<ans;
    }
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int t = 1;
    while(t--){
        solve();
    }
}

5. ACM中的CM题

赛时考虑用二分答案,但是似乎答案单调性有问题???,一直分不出来,看了题解还是用暴力做吧。

可能考虑的过程错了,和题解计算二分的地方不一样,题解计算的是算给定的m值后需要的数来覆盖所有地雷,

直接二分m的值可能会有遗漏??

#include<bits/stdc++.h>
using namespace std;
using LL = long long ;
vector<int>a;
int check(int x) {
    int ans = x;
    int pos = a[1];
    while (1) {
        ans++;
        pos = std::upper_bound(a.begin() + 1, a.end(), pos + x) - a.begin();
        if (pos == a.end() - a.begin()) break;
        pos = a[pos];
    }
    
    return ans;
}
int main()
{
    int n;
    cin>>n;
    a.push_back(0);
    for(int i=1;i<=n;i++)
    {
        int x;
        cin>>x;
        a.push_back(x);
    }
    sort(a.begin()+1,a.end());
    int ans = 1e6;
    for(int i=0;i<n;i++)
    {
        ans=min(ans,check(i));
    }
    cout<<ans<<endl;
    
}