Codeforces Round 1031 (Div. 2)补题

地址


A烧烤温度

贪心思路比较容易想到的。

错:
写成z1=max(0,(k-b)/y+1); 以为k<b时能正确处理
实际上会abs(k-b)<y时,z1=1,会出错。
z2也一样

点击查看代码
#include<bits/stdc++.h>
using namespace std;

void solve(){
    int k,a,b,x,y;
    cin>>k>>a>>b>>x>>y;
    int ans,z1=0,z2=0;
    if(x>y){
        if(k>=b){
            z1=(k-b)/y+1;
            k-=z1*y;
        }
        if(k>=a){
            z2=(k-a)/x+1;
        }
        ans=z1+z2;
    }else{
        if(k>=a){
            z1=(k-a)/x+1;
            k-=z1*x;
        }
        if(k>=b){
            z2=(k-b)/y+1;
        }
        ans=z1+z2;
    }
    cout<<ans<<endl;
    return ;
}

signed main(){
    int t;
    cin>>t;
    while(t--) solve();
    return 0;
}

B屋顶板覆盖屋顶

贪心思路也是比较容易想的
外围是可以延伸出去的,借助外围向外铺屋顶板,矛盾就在内部

错:
以为只有当最初的两块屋顶板x方向有重叠或y方向有重叠时才需要判断dif是否被a或b边整除
实际上画图得出不论重叠与否,difx和dify至少有一个能够整除a或b才是Yes,否则为No(在x方向和y方向不重叠的前提下)
1.特判if(x1=x2)和if(y1=y2) 这种情况下一个dif为0一定可以满足,但是需保证另一个dif必须满足,即两个dif满足
2.else的情况(x有交集或y有交集或都没有交集)两个dif至少有一个满足就能借助外围的特性塞满。

trick:
求dif时可以直接用两个左下顶点x和y分别相减求得
求得的dif正好是一个a或b加上需要的dif(在相离的情况下)
或者不足一个a或b(在相交的情况下)
取模时不会受到影响

点击查看代码
#include<bits/stdc++.h>
using namespace std;

void solve(){
    int w,h,a,b,x1,y1,x2,y2;
    cin>>w>>h>>a>>b>>x1>>y1>>x2>>y2;

    if(x1==x2){
        int dif=abs(y1-y2)%b;
        if(dif) cout<<"No"<<endl;
        else cout<<"Yes"<<endl;
        return ;
    }
    if(y1==y2){
        int dif=abs(x1-x2)%a;
        if(dif) cout<<"No"<<endl;
        else cout<<"Yes"<<endl;
        return ;
    }

    if(abs(x1-x2)%a&&abs(y1-y2)%b) cout<<"No"<<endl;
    else cout<<"Yes"<<endl;
    return ;
}

signed main(){
    int t;
    cin>>t;
    while(t--) solve();
    return 0;
}

C金苹果二维前缀和

贪心:
发现选择一个区域用炸弹炸掉后
每次一格一格地移动,可以获得其余所有的金锭
ans=sum-毁掉的金锭

遍历所有的格子,
如果是空地,计算产生爆炸毁掉的金锭数,存最小的毁掉的金锭数
快速计算爆炸范围内毁掉的金锭数:二维前缀和\(O(1)\)实现

二维前缀和实现细节和一维其实差不多
前面也是用0来更新,后面注意二维数组越界的问题

trick:
当二维前缀和数组面对越界风险时,
可以max(i-k,0)min(i+k-1,n)
来替换为边界值和0,可以画图很快证明,
对于边界值,超出的部分为空的,超一维还是超两维对应的值都是m和n分别替换后的值
对于0,只要超出0界了,就一定是空的,而0对应的也是空的,所以超一维还是超两维也都是用0替换相应的值

点击查看代码
#include<bits/stdc++.h>
using namespace std;

void solve(){
    int n,m,k;
    cin>>n>>m>>k;
    vector<vector<char>> a(n+1,vector<char>(m+1));
    vector<vector<int>> s(n+1,vector<int>(m+1));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++) cin>>a[i][j];


    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++) s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+(a[i][j]=='g');

    int sum=s[n][m];
    int ans=s[n][m];

    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(a[i][j]=='.'){
                int res=s[min(i+k-1,n)][min(j+k-1,m)]-s[max(i-k,0)][min(j+k-1,m)]-s[min(i+k-1,n)][max(j-k,0)]+s[max(i-k,0)][max(j-k,0)];
                ans=min(ans,res);
            }
    

    cout<<sum-ans<<endl;
    return ;
}

signed main(){
    int t;
    cin>>t;
    while(t--) solve();
    return 0;
}
posted @ 2025-11-08 15:45  gudelaike  阅读(1)  评论(0)    收藏  举报