At 407 ABCDE

A.Approximation


原题链接

简述题意

四舍五入求a/b的值

AC code

void solve(){
    int n,m;cin>>n>>m;
    cout<<round(1.0*n/m)<<endl;
}

B.P(X or Y)


原题链接

简述题意

枚举 \([1,6]\) 构成的所有无序对,求满足以下两种其一的概率,无序对两元素之和大于等于a,无序对两元素绝对值差大于等于b

AC code

void solve(){
    ll ans=0;
    int a,b;cin>>a>>b;
    for(int i=1;i<=6;i++){
        for(int j=1;j<=6;j++){
            ans+=(i+j>=a||abs(i-j)>=b);
        }
    }
    cout<<fixed<<setprecision(15)<<1.0L*ans/36<<endl;
}

C.Security 2


原题链接

简述题意

给定一个初始为空的数字字符串,现在有两种操作,操作一,在字符串末尾添加0,操作二,使字符串每个元素都增加1,数字对应转化为\(0 1 2 3 4 5 6 7 8 9->1 2 3 4 5 6 7 8 9 0\),现在想要求初始字符串到目标字符串的最小操作数

解题思路

单独考虑每一位字符和下一位字符的关系,当前字符一定比下一位字符生成的早,并且早的时间内进行操作二的次数最好是在0~10之内的,这样就得到了比较显然的思路,顺序枚举每一个位置,统计后一位比当前位置多使用的操作二(\(mod\,10\)),对于末尾元素单独统计,最后再加上字符串长度

AC code

void solve(){
    string s;cin>>s;
    int n=s.size();
    ll ans=0;
    for(int i=0;i<n-1;i++){
        ans+=(s[i]-s[i+1]+10)%10;
    }
    ans+=s.back()-'0';
    ans+=n;
    cout<<ans<<endl;
}

D.Domino Covering XOR

原题链接

题意简述

给定一个长为 \(n\) 宽为 \(m\) 的矩阵,要求放置任意长为 \(2\) 宽为 \(1\) 的小木条遮住矩阵上任意元素,其中小木条不可与小木条重叠,也不可超过矩阵范围,放置次数不限,要求求解没有被遮住的元素最大异或和

解题思路

对于每一位 \(a_{ij}\) 单独考虑,他对结果产生贡献的方式有三种,1.被横着遮住,2.被竖着遮住,3.没被遮住,分别对应 \(a_{i,j}\)\(a_{i+1,j}\)不异或,\(a_{i,j}\)\(a_{i,j+1}\)不异或,由于数据范围十分小,考虑从起点开始深度搜索,枚举三种情况,时间复杂度\(O(n·m·2^{n·m})\)

AC code

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const int N=25;
ll a[N][N];
bool vis[N][N];
ll ans;
int n,m;
void dfs(int k,ll t){
    if(k==n*m){
        ans=max(ans,t);
        return;
    }
    int x=(k-1)%n+1,y=(k-1)/n+1;
    if(!vis[x][y]&&!vis[x+1][y]&&x<n){
        vis[x][y]=vis[x+1][y]=1;
        dfs(k+1,t^a[x][y]^a[x+1][y]);
        vis[x][y]=vis[x+1][y]=0;
    }
    if(!vis[x][y]&&!vis[x][y+1]&&y<m){
        vis[x][y]=vis[x][y+1]=1;
        dfs(k+1,t^a[x][y]^a[x][y+1]);
        vis[x][y]=vis[x][y+1]=0;
    }
    dfs(k+1,t);
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>a[i][j];
        }
    }
    ll t=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            t^=a[i][j];
        }
    }
    dfs(1,t);
    cout<<ans<<endl;
    return 0;
}

E.Most Valuable Parentheses


原题链接

题意简述

给定一个长为\(2·n\)的序列 \(a\) ,要求他匹配任意可能的括号序列,使得对应左括号产生 \(a_i\) 贡献而右括号对结果不产生贡献,求序列最大贡献

解题思路

括号序列有以下性质,对于每个 \(2·k-1\) 的位置都必定有k个左括号,第一个位置必定是左括号,从这个性质出发,贪心的选择左括号,每一轮选定一个左括号。对于第 \(k\) 轮产生的左括号,他一定是在第 \(2·k-1\) 个位置之前。这样枚举 \([1,n]\) $ n $轮,每轮更新可能成为左括号的位置\(2·k-1\)\(2·k-2\),其中第 \(1\) 轮的左括号一定在第 \(1\) 个位置。

AC code

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
void solve(){
    int n;cin>>n;
    vector<int>a(n<<1|1);
    for(int i=1;i<=(n<<1);i++) cin>>a[i];
    priority_queue<ll>Q;
    ll ans=a[1];
    for(int i=2;i<=n;i++){
        Q.push(a[i*2-1]);
        Q.push(a[i*2-2]);
        ans+=Q.top();
        Q.pop();
    }
    cout<<ans<<endl;
}
int main(){
    cin.tie(0)->ios::sync_with_stdio(false);
    int T=1;cin>>T;
    while(T--) solve();
    return 0;
}
posted @ 2025-05-25 11:20  usedchang  阅读(78)  评论(0)    收藏  举报