SMU Summer 2024 Contest Round 5

SMU Summer 2024 Contest Round 5

2024.7.19 9:00————12:00

过题数1/7
补题数4/7

  • Robot Takahashi
  • Connect 6
  • Strange Balls
  • Linear Probing
  • Red Polyomino
  • Stronger Takahashi
  • Predilection

A - Robot Takahashi

我太菜了dbq
一开始想用三分,写完交上去发现错了,细细想了一下发现这题不能用三分,是一道非常波折的曲线。然后用了俩个循环,tle了,然后循环加三分,结果又wa了,一个小时过去了。

题解:
n个人,有大人或小孩,各自有自己对应的体重w[i],d对应位置上是1它就是大人,否则就是小孩,有一个小机器人,它会武断地将大于等于X体重的人当作大人,其余是小孩,请问它最多可以判断正确多少次。
将大人和小孩分别储存进b和a排序,对大人进行遍历,另x等于大人,所以满足条件的大人会一一减少,而小孩则会增多,直接从当前遍历到的a的位置继续遍历,找到第一个不满足条件的小孩停止即可。输出最大的ans。
代码:

#include<bits/stdc++.h>

using namespace std;
#define int long long
int n;
string s;
int w[200006];
priority_queue<int,vector<int>,greater<int>>b;
int a[200005];

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    cin >> s;
    int jsa = 0;
    for (int i = 1; i <= n; i++) {
        cin >> w[i];
        if(s[i-1]=='0'){
            a[jsa] = w[i];
            jsa++;
        }
        else if(s[i-1]=='1')b.push(w[i]);
    }sort(a,a+jsa);
    int t = 0;
    int res = b.size();
    int ans = 0;
    if(res == 0) ans = n;
    int m = 0;
    while (!b.empty()) {
        t++;
        int la = res-t+1;
        int x = b.top();
        b.pop();
        for (m; m < jsa; m++) {
            if(a[m] >= x)break;
        }//这个地方一开始我是直接遍历a,所以会t,可以想到满足条件的a绝对会越来越多,直接从上一个位置往下遍历即可。
        la = la+m;
//        cout << la << endl;
        ans = max(ans,la);
    }
    cout << ans;
    return 0;
}

B - Connect 6

题解:
n行n列的字符数组,‘#’是黑色,'.'是白色。可以将任意俩块变成黑色,能否是竖直方向,水平方向,或者对角方向有连续的六个黑色块。
直接暴力即可,看连续的六个能否有四个黑色块,注意不能跑到最后五个块进行遍历,因为他们所需要的黑色块是在数组之外的。
代码:

#include<bits/stdc++.h>

using namespace std;
#define int long long
int n;
char a[1015][1015];

signed main() {
    cin >> n;
    for (int i = 1; i <= 1010; i++) {
        for (int j = 1; j <= 1010; j++) {
            a[i][j] = '!';
        }
    }
    
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cin >> a[i][j];
        }
    }

    bool st = false;
    int res = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if(j+5<= n){
            //就是这几个if,wa了好几次,如果不加的话说明你所需要的黑色块在数组之外,无法实现
            res = 0;
            for (int k = 0; k < 6; k++) if(a[i][j+k] == '#')res++;
            if(res >=4)st = true;}
            
            if(i+5 <= n){
            res = 0;
            for (int k = 0; k < 6; k++) if(a[i+k][j] == '#')res++;
            if(res >= 4)st = true;}
            
            if(i+5 <= n && j+ 5 <= n){
            res = 0;
            for (int k = 0; k < 6; k++) if(a[i+k][j+k] == '#')res++;
            if(res >= 4)st = true;}
            
            res = 0;
            if(j >= 6 && i+5 <= n) {
                for (int k = 0; k < 6; k++) if(a[i+k][j-k]=='#')res++;
                if(res >= 4)st = true;
            }
            
            res = 0;
            if(i >= 6 && j+5 <= n) {
                for (int k = 0; k < 6; k++) if(a[i-k][j+k]=='#')res++;
                if(res >= 4)st = true;
            }
            
        }
    }
    if(st)cout << "Yes" << endl;
    else cout << "No" << endl;
    return 0;
}

C - Strange Balls

题解:
有n个球,保证每个球上的数字大于1,往一个气缸里一个一个放球,如果有连续k个标号为k的球,它们就会被消除,求每次往里面放入球后的个数。
愣是给我暴力出来了,然后看了一下应该是可以二维stack储存个数。
代码:

#include<bits/stdc++.h>

using namespace std;
#define int long long
int n;
int a[200005];
int b[200005];

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    //加速加速加速
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    int t = 1;
    for (int j = 1; j <= n; j++) {
        b[t] = a[j];
        if(t >= a[j]) {
            bool st = true;
            for (int k = t-a[j]+1; k <= t; k++) {
                if(b[k] != a[j]){
                    st = false;
                    break;
                    //可以停下这个对比标号了
                }
            }
            if(st) {
                t = t-a[j];
            }
        }
        cout << t << endl;
        t++;
    }
    return 0;
}
//也是没想到竟然过了
#include<bits/stdc++.h>

using namespace std;
#define int long long
int n;
int a[200005];
stack<pair<int,int>>b;
//标号与连续的个数

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    int res = 0;
    for (int i = 1; i <= n; i++) {
        if(b.empty()) {
            b.push({a[i],1});
            res++;
        }
        else if(a[i] == b.top().first) {
            b.top().second++;
            res++;
            if(a[i] == b.top().second) {
                res-=a[i];
                b.pop();
            }
        }
        else {
            b.push({a[i],1});
            res++;
        }
        cout << res << endl;
    }
    return 0;
}

D - Linear Probing

题解:
给定一个长度为n且每个数都是-1的数组a,q次询问,每个询问输入t和x,如果t=1,令h=x%n,在数组a中找到第一个为-1的数字,变成x。如果t=2,直接输出a[x%n]。
可以考虑到,在寻找第一个为-1的数字时会出现反复重复遍历同一段数组的情况,所以定义一个to数组,每次直接跳跃过去已经确定过都不是-1的数组,具体见注释。
代码:

#include<bits/stdc++.h>

using namespace std;
#define int long long 
const int N = 1048576;
int a[1050000];
int q,lq;
int to[1050000];

void dfs(int t,int x) {
    if(a[t] == -1) {
        lq = t;
        //当前这个不为-1的,标记一下
        a[t] = x;
        return ;
    }
    dfs(to[t],x);
    to[t] = lq;
    //在回来的路上把沿途的to都直接赋值到最后一个lq
}

signed main() {
    cin >> q;
    memset(a,-1,sizeof a);
    for (int i = 0; i < N; i++) {
        to[i] = i+1;
    }to[N-1] = 0;
    while (q--) {
        int t,x;
        cin >> t >> x;
        if(t == 1) {
            int h = x;
            dfs(h%N,x);
        }
        else if(t == 2) cout << a[x%N] << endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值