Codeforces div2 C题补题

Codeforces div2 C题补题

1922 C. Closest Cities

C. Closest Cities

很容易看出,端点的两个城市的最近城市就是他的直接后继和直接前驱,而中间的城市的最近城市就是他前驱和后继中距离绝对值最小的那个,因此我们可以先预处理出每个城市对应的最近城市,用map存储。

然后因为区间可以从左向右走也可以从右向左走,因此我们可以求出其前缀后缀和,前缀和表示从左向右的花费总和,后缀和表示从右向左的花费总和,在求前缀后缀和的时候,下一个如果恰好是距离最近的城市,我们就贪心地直接花费1块钱直接去那,否则就花费其距离的绝对值。

这样的话我们在进行询问的时候直接pre[r]pre[l]就可以O(1)求出l到r的最短距离了

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define int long long
using ull = unsigned long long;                                                                             
using ll = long long;
using i128 = __int128_t;
using pii = pair<int,int>;
using psi = pair<string,int>;
constexpr ll MOD = 1e9+7;
//-------------------------------------------------------->>>>>>>>>>
inline void solve(){
    int n;
    cin>>n;
    vector<int> a(n+1,0);
    map<int,int> nest;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    nest[1]=2;
    nest[n]=n-1;
    for(int i=2;i<n;i++){
        if(abs(a[i-1]-a[i])<abs(a[i+1]-a[i])){
            nest[i]=i-1;
        }else{
            nest[i]=i+1;
        }
    }
    vector<int> pre(n+1,0);
    pre[1]=0;
    for(int i=2;i<=n;i++){
        if(i==nest[i-1]){
            pre[i]=pre[i-1]+1;
        }else{
            pre[i]=pre[i-1]+abs(a[i]-a[i-1]);
        }
    }
    vector<int> suf(n+2,0);
    suf[n]=0;
    for(int i=n-1;i>=1;i--){
        if(i==nest[i+1]){
            suf[i]=suf[i+1]+1;
        }else{
            suf[i]=suf[i+1]+abs(a[i]-a[i+1]);
        }
    }
    int m;
    cin>>m;
    while(m--){
        int l,r;
        cin>>l>>r;
        if(l>r) cout<<suf[r]-suf[l]<<"\n";
        else cout<<pre[r]-pre[l]<<"\n";
    }
}
inline void prework(){
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);
    cout<<fixed<<setprecision(12);
    prework();
    int T=1; 
    cin>>T;
    while(T--){
        solve();
    }
    return 0;
}

1895 C. Torn Lucky Ticket

C. Torn Lucky Ticket

从字符串的最大长度不超过5可以猜到一定是可以枚举长度的,我们可以先把每个字符串stri的数位总和和长度记录下来,用map存储,然后枚举stristri能够与哪些字符串构成符合要求的数字,然后枚举stri的长度cnt作为其左半部分,这样的话右半部分剩余的长度就是rem=stri.size()cnt,需要补足的长度就是cntrem,这样我们之前存储的map就有用了,我们可以根据其总和和长度判断是否存在,有几个这样的字符串合法,mp[{cntrem,pre(totpre)}],pre是枚举到字符串前i个字符的数位总和,这样便可以获取数量,因为可以左右拼也可以右左拼,所以还要再反向处理一遍,注意的是,因为可以和自己拼,所以前后各走一遍会重复,所以当枚举长度等于字符串长度时,加一遍就行了。

AC代码如下:

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define int long long
using ull = unsigned long long;                                                                             
using ll = long long;
using i128 = __int128_t;
using pii = pair<int,int>;
using psi = pair<string,int>;
constexpr ll MOD = 1e9+7;
//-------------------------------------------------------->>>>>>>>>>
inline void solve(){
    int n;
    cin>>n;
    vector<string> a(n);
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    map<pii,int> tok;
    for(int i=0;i<n;i++){
        int tot=0;
        for(int j=0;j<a[i].size();j++){
            tot+=a[i][j]-'0';
        }
        tok[{a[i].size(),tot}]++;
    }
    int ans=0;
    for(int i=0;i<n;i++){
        int tot=0;
        for(int j=0;j<a[i].size();j++){
            tot+=a[i][j]-'0';
        }
        int cnt=0;
        int pre=0,suf=0;//pre从前向后,suf从后向前
        for(int j=0;j<a[i].size();j++){
            cnt++;
            pre+=a[i][j]-'0';
            suf+=a[i][a[i].size()-j-1]-'0';
            int rem=a[i].size()-cnt;
            ans+=tok[{cnt-rem,2*pre-tot}];
            if(!(j==a[i].size()-1)){//如果j=a.size,suf就不累计进去了
                ans+=tok[{cnt-rem,2*suf-tot}];
            }
        }
    }
    cout<<ans<<"\n";
}
inline void prework(){
    
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);
    cout<<fixed<<setprecision(12);
    prework();
    int T=1; 
    // cin>>T;
    while(T--){
        solve();
    }
    return 0;
}

1904 C. Array Game

C. Array Game

分类讨论,双指针

可以发现,当m3时一定为0,因为可以随便选择两个数字处理两次得到两个相同的数,再将这两个数相减,就一定是0

当m=1时,直接O(n2)枚举就行,因为n很小

当m=2时,先排序,再用双指针求最小值就行,之前用了map<int,vector<int>>存储,虽然也是O(n2)复杂度,但会MLE。

注意要先把原数组扫一遍取最小值

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f3f3f3f3f
#define int long long
using ull = unsigned long long;                                                                             
using ll = long long;
using i128 = __int128_t;
using pii = pair<int,int>;
using psi = pair<string,int>;
constexpr ll MOD = 1e9+7;
//-------------------------------------------------------->>>>>>>>>>
inline void solve(){
    int n,m;
    cin>>n>>m;
    vector<int> a(n);
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    if(m>=3){
        cout<<0<<"\n";
        return;
    }
    int maxn=INF;
    if(m==2){
        int ans = INF;
        sort(all(a));
        for (int j = 0; j < n; j++){
            ans = min(ans, a[j]);
        }
        for (int j = 0; j < n; j++){
            int p = 0;
            for (int l = j + 1; l < n; l++){
                while (p < n){
                    if (a[p] < a[l] - a[j]){
                        p++;
                    } else {
                        break;
                    }
                }
                ans = min(ans, a[l] - a[j]);
                if (p > 0){
                    ans = min(ans, (a[l] - a[j]) - a[p - 1]);
                }
                if (p < n){
                    ans = min(ans, a[p] - (a[l] - a[j]));
                }
            }
        }
        cout << ans << "\n";
        return;
    }
    if(m==1){
        for (int j = 0; j < n; j++){
            maxn = min(maxn, a[j]);
        }
        for(int i=1;i<n;i++){
            for(int j=0;j<i;j++){
                maxn=min(maxn,abs(a[j]-a[i]));
            }
        }
        cout<<maxn<<"\n";
        return;
    }
}
inline void prework(){
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);
    cout<<fixed<<setprecision(12);
    prework();
    int T=1; 
    cin>>T;
    while(T--){
        solve();
    }
    return 0;
}
posted @   KrowFeather  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示