河南萌新联赛2024第(六)场:郑州大学

PREFACE:

本人菜鸡,只能把简单题补了,本文章没有EJKL
这场人好少,牛客多校之后没人了,没兴致打了说是

A.装备二选一(一)

假设攻击一百次,计算出100次的总伤害

void solve(){
    int a,b,c,d;
    cin>>a>>b>>c>>d;
    
    ll ans1 = (100-a)*1+a*b;
    ll ans2 = (100-c)*1+c*d;
    if(ans1>=ans2){
        cout<<"NO"<<endl;
    }else{
        cout<<"YES"<<endl;
    }
}

F-追寻光的方向

倒序扫一遍数组求一个递增的序列,然后双指针扫一遍看有几个数字就行了

void solve(){
    int n;
    cin>>n;
    vector<int> a(n+1);
    for(int i = 1;i<=n;i++) cin>>a[i];
    for(int i = n-1;i>=1;i--){
        a[i] = max(a[i],a[i+1]);
    }
    int ans = 0;
    for(int i = 1;i<=n;i++){
        int j = i;
        if(a[j]==a[j+1]&&j+1<=n){
            while(a[j]==a[j+1]&&j+1<=n) j++;
            ans++;
            i = j;
        }else{
            ans++;
        }
    }
    cout<<ans-1<<endl;
}

B-百变马楼

纯大暴力,无敌了模拟,wa了两发把两种特判加上就对了,普通情况就是双指针,特殊情况形如aab和aaab,eeee和eeeee

void solve(){
    string a;
    string b;
    cin>>a>>b;
    int len  = a.size();
    int posi = len-1;
    
    for(int i = 0;i<len;i++){
        if(a[i]!=b[i]){
            if(a[i]!=b[i+1]){
                cout<<"0";
                return ;
            }
        }
    }
    
    char st = a[0];
    bool sucsta = false;
    bool sucstb = false;
    for(int i = 0;i<=len;i++){
        if(b[i]!=st) break;
        if(i==len){
            sucstb= true;
        }
    }
    for(int i = 0;i<len;i++){
        if(a[i]!=st) break;
        if(i==len-1){
            sucsta = true;
        }
    }
    
    if(sucsta&&sucstb){
        cout<<len+1<<endl;
        for(int i = 0;i<=len;i++){
            cout<<i<<' '<<st<<endl;
        }
        return ;
    }
    
    for(int i = 0;i<len;i++){
        if(a[i]==b[i]){
            if(i==len-1){
                
                cout<<1<<endl<<len<<' '<<b[len];
                return ;
            }
        }else{
            break;
        }
    }
    
    for(int i = 0;i<len;i++){
        if(a[i]!=b[i]){
            posi = i;
            break;
        }
    }
   char ans = b[posi];
//     posi++;
    int j = posi;
    if(b[j]==b[j-1]&&j-1>=0){
        while(b[j]==b[j-1]&&j-1>=0) j--;
    }
    cout<<posi-j+1<<endl;
    for(int i = j;i<=posi;i++){
        cout<<i<<' '<<ans<<endl;
    }
}

I-正义从不打背身

照例手玩,手玩后发现是奇数递减后偶数递增或者偶数递减后奇数递增,和m的奇偶有关,并且每一位的操作数是m-i+1次,所以很简单的手玩(用st来表示每个位置的状态,再先处理每一位m次之后的状态,最后确定位置)

const int N = 2e6+10;
int st[N];
int ans[N];
int idx = 1;
void solve(){
    int n,m;
    cin>>n>>m;
//     vector<int> st(n+1);
    st[0] = 0;
    string a;
    cin>>a;
    for(int i = 1;i<=n;i++){
        if(a[i-1]=='P'){
            st[i] = 0;
        }else{
            st[i] = 1;
        }
    }
    
    for(int i = 1;i<=m;i++){
        int cnt = m-i+1;
        if(cnt%2==0){
            ;
        }else{
            st[i] = st[i]^1;
        }
    }
    
    if(m%2==1){
        for(int i = m;i>=1;i-=2) ans[idx] = st[i],idx++;
        for(int i = 2;i<=m-1;i+=2) ans[idx] = st[i],idx++;
        for(int i = m+1;i<=n;i++) ans[idx] = st[i],idx++;
    }else{
        for(int i = m;i>=2;i-=2) ans[idx] = st[i],idx++;
        for(int i = 1;i<=m-1;i+=2) ans[idx] = st[i],idx++;
        for(int i = m+1;i<=n;i++) ans[idx] = st[i],idx++;
    }
    
    for(int i = 1;i<=n;i++){
        cout<<(ans[i]^1)<<' ';
    }
}

D-四散而逃

wa一发后首先发现跟两边的数字没有任何关系,并且中间的数字不能是全为奇数,所以要至少有一个偶数,所以可以得到先把偶数分给奇数使奇数变为偶数然后再让奇数逃走,并且还发现,只要有一个偶数就行了,因为1可以传递,所以偶数的逃逸次数是(x/2)奇数的逃逸次数就是(x+1)/2;


void solve(){
    int n;
    cin>>n;
    vector<int> a(n+4);
    for(int i = 1;i<=n;i++){
        cin>>a[i];
    }
    int ans = 0;
    bool f = 0;
    for(int i = 2;i<=n-1;i++){
        if(a[i] > 1) f = 1;
        ans += (a[i]+1)/2;
    }
    if(n == 3 && a[2]%2) f = 0; 
    if(f) cout<<ans<<endl;
    else cout<<"-1\n";
}

C 16进制世界

一开始想的是直接01背包套下判断条件,就是dp[i-1][j]是16倍数那么考虑不加入第n个物品

如果(dp[i-1][j-v[i]]+w[i])%16==0,那么就加入,最后算出最大dp值然后记录路径输出就好了,

怒wa一发,手玩2 1 2 15 直接错了

//WA
const int N = 1e5+10;
int v[N];
int w[N];

void solve(){
    int n,m;
    cin>>n>>m;
    int dp[n+1][m+1];
    int p[n+1][m+1];
    memset(dp,0,sizeof(dp));
    memset(p,0,sizeof(p));
    
    for(int i = 1;i<=n;i++){
        cin>>v[i]>>w[i];
    }
    for(int i = 1;i<=n;i++){
        for(int j = 0;j<=m;j++){
            dp[i][j] = dp[i-1][j];
            if(j>=v[i]&&(dp[i-1][j-v[i]]+w[i])%16==0){
                dp[i][j] = max(dp[i][j],dp[i-1][j-v[i]]+w[i]);
                p[i][j] = 1;
            }
        }
    }
    
    int ans = 0;
    int i=n,j=m; 
    while(i>=0&&j>=0){
        if(p[i][j]) 
			{
                ans++;
				j-=v[i];  
			}
			i--; 
		}
    cout<<ans<<endl;
}

赛后看大佬的代码都是取模运算,直接粘官方题解吧,出自官方题解

 G-等公交车

我们在距离为 dd 的车站在 tt 时刻开始等候,其实就相当于我们在距离为 00 的车站在 t−d 时刻开始等候。因为一辆车在某个时间到距离为 d 的车站,那么在 d 分钟前一定到距离为 0 的车站,所以两者的到站顺序是完全一致的,所以直接对t-d二分就行了

const int N = 1e5+10;
int d[N],t[N];
void solve(){
    int n,m;
    cin>>n>>m;
    
    for(int i = 1;i<=n;i++) cin>>d[i];
    for(int j = 1;j<=m;j++) cin>>t[j];
    
    int q;
    cin>>q;
    
    while(q--){
        int tt,x;
        cin>>tt>>x;
        tt-=d[x];
        auto iter = lower_bound(t+1,t+1+m,tt);
        if(iter-t>m)cout<<"TNT"<<endl;
        else cout<<*iter-tt<<endl;
    }
}

H-24点

纯纯是来攻击代码能力了,菜鸡不会,建议看题解官方题解

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值