2025牛客寒假算法基础集训营2

寒假第二场牛客训练营。

过题数 7/13,

过题数有所增加,排名基本不变。赛时签到题手速很快,但之后写题犯浑导致吃罚时较多。但最后还是脑子不够,导致排名被限制。

有一道几何题,规律已经找到,但差在一点契机导致没有通过。如果平时再努力一点就好了。

A. 一起奏响历史之音!

输入一行7个整数,如果数组中有4和7就输出 NO, 否则输出 YES

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
typedef pair<int, int> PII;
const int N = 2e5 + 7;
const int inf = LLONG_MAX / 10;
const int mod = 998244353;
// const int mod = 1e9 + 7;
#define x first
#define y second
//二分暴龍龍

void miaojiachun()
{
    int a[8];
    int flag=1;
    for(int i=1;i<=7;i++){
        cin>>a[i];
        if(a[i]!=1 and a[i]!=2 and a[i]!=3 and a[i]!=5 and a[i]!=6){
            flag=0;
        }
    }
    if(flag){
        cout<<"YES"<<endl;
    }else{
        cout<<"NO"<<endl;
    }
}
signed main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int ING = 1;
    // cin >> ING;
    while (ING--)
    {
        miaojiachun();
    }
    return 0;
}

B.能去你家蹭口饭吃吗

找到恰好小于数组中一半数字的最大数

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
typedef pair<int, int> PII;
const int N = 2e5 + 7;
const int inf = LLONG_MAX / 10;
const int mod = 998244353;
// const int mod = 1e9 + 7;
#define x first
#define y second
//二分暴龍龍

void miaojiachun()
{
    int n;
    cin>>n;
    vector<int>a(n+1);
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    sort(a.begin(),a.end());
    int k=0;
    if(n%2==1){
        k=n/2+1;
    }else{
        k=n/2+1;
    }
    cout<<a[k]-1<<endl;
}
signed main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int ING = 1;
    // cin >> ING;
    while (ING--)
    {
        miaojiachun();
    }
    return 0;
}

F.一起找神秘的数!

对于给定的区间 l 到 r,从中选取两个整数 x 和
y,使得下式成立:

x + y = ( x or y ) + ( x and y ) + ( x xor y )

眼力题,由观察和过题人数可得。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
typedef pair<int, int> PII;
const int N = 2e5 + 7;
const int inf = LLONG_MAX / 10;
const int mod = 998244353;
// const int mod = 1e9 + 7;
#define x first
#define y second
//二分暴龍龍

void miaojiachun()
{
    int l,r;
    cin>>l>>r;
    cout<<r-l+1<<endl;
}
signed main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int ING = 1;
    cin >> ING;
    while (ING--)
    {
        miaojiachun();
    }
    return 0;
}

G.一起铸最好的剑

找到数字 m 的第几次方最接近 n,注意坑点为 1,1 的任何次方都不会变。 直接输出 1。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
typedef pair<int, int> PII;
const int N = 2e5 + 7;
const int inf = LLONG_MAX / 10;
const int mod = 998244353;
// const int mod = 1e9 + 7;
#define x first
#define y second
//二分暴龍龍

void miaojiachun()
{
    int n,m;
    cin>>n>>m;
    int num=1;
    int m1=m;
    if(m1==1){
        cout<<1<<endl;
        return;
    }
    while(m1*m<=n){
        m1*=m;
        num++;
    }
    if(m1*m-n<n-m1){
        num++;
    }
    cout<<num<<endl;
}
signed main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int ING = 1;
    cin >> ING;
    while (ING--)
    {
        miaojiachun();
    }
    return 0;
}

J.数据时间?

煞笔模拟,骗我罚时。 煞笔我,看不出错。

这个就是按照题目进行模拟,结构体进行记录,然后从字符串中筛选出符合条件的人选。在存进一个数组中进行计数就好,这题当时写麻了,以为数据类新给的比较出错了,所以才有这么麻烦的代码。

死因是由于map的记录。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
typedef pair<int, int> PII;
const int N = 2e5 + 7;
const int inf = LLONG_MAX / 10;
const int mod = 998244353;
// const int mod = 1e9 + 7;
#define x first
#define y second
//二分暴龍龍
struct user{
    string id;
    string date;
    string time;
    int ti;
};
bool cmp(user a,user b){
    if(a.date==b.date){
        return a.time<b.time;
    }
    return a.date<b.date;
}
void miaojiachun()
{
    int n,h,m;
    cin>>n>>h>>m;
    vector<user>a(n+1);
    vector<user>b;
    for(int i=1;i<=n;i++){
        cin>>a[i].id>>a[i].date>>a[i].time;
        // cout<<a[i].id<<" "<<a[i].date<<" "<<a[i].time<<endl;
        string d1="";
        d1+=a[i].date[0];
        d1+=a[i].date[1];
        d1+=a[i].date[2];
        d1+=a[i].date[3];
        string h1="";
        h1+=a[i].date[5];
        h1+=a[i].date[6];
        int d2=(d1[0]-'0')*1000+(d1[1]-'0')*100+(d1[2]-'0')*10+(d1[3]-'0');
        int h2=(h1[0]-'0')*10+(h1[1]-'0');
        // cout<<d1<<" "<<h1<<endl;
        string tt="";
        tt+=a[i].time[0];
        tt+=a[i].time[1];
        tt+=a[i].time[3];
        tt+=a[i].time[4];
        tt+=a[i].time[6];
        tt+=a[i].time[7];
        a[i].time=tt;
        a[i].ti=(tt[0]-'0')*100000+(tt[1]-'0')*10000+(tt[2]-'0')*1000+(tt[3]-'0')*100+(tt[4]-'0')*10+(tt[5]-'0');
        // cout<<d2<<" "<<h2<<endl;
        // cout<<a[i].ti<<endl;
        if(d2==h and h2==m){
            b.push_back(a[i]);
        }
    }
    int num1=0,num2=0,num3=0;
    // sort(b.begin(),b.end(),cmp);
    map<string,int>u1,u2,u3;
    for(int i=0;i<b.size();i++){
        if((b[i].ti>=70000 and b[i].ti<=90000 ) or (b[i].ti>=180000 and b[i].ti<=200000) and u1[b[i].id]==0){
            u1[b[i].id]++;
            num1++;
        }
    }for(int i=0;i<b.size();i++){
        if((b[i].ti>=110000 and b[i].ti<=130000 ) and u2[b[i].id]==0){
            u2[b[i].id]++;
            num2++;
        }
    }for(int i=0;i<b.size();i++){
        if((b[i].ti>=220000 and b[i].ti<=235959) or (b[i].ti>=0 and b[i].ti<=10000) and u3[b[i].id]==0){
            u3[b[i].id]++;
            num3++;
        }
    }
    cout<<num1<<" "<<num2<<" "<<num3<<endl;
}
signed main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int ING = 1;
    // cin >> ING;
    while (ING--)
    {
        miaojiachun();
    }
    return 0;
}

K.可以分开吗?

搜索题,查找连通块,然后在查找过程中记录要敲碎的方块数。遍历的所有结果取最小值。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
typedef pair<int, int> PII;
const int N = 2e5 + 7;
const int inf = LLONG_MAX / 10;
#define x first
#define y second

const int dx[] = {-1, 1, 0, 0};
const int dy[] = {0, 0, -1, 1};

int mink(int n, int m, vector<string>& g) {
    int minks = INT_MAX;
    vector<vector<bool>> visited(n, vector<bool>(m, false));

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (g[i][j] == '1' && !visited[i][j]) {
                queue<PII> q;
                q.push({i, j});
                visited[i][j] = true;
                vector<PII> cur;
                cur.push_back({i, j});

                // 使用一个集合来存储需要敲碎的灰色砖块
                set<PII> breaks;

                while (!q.empty()) {
                    auto [x, y] = q.front();
                    q.pop();

                    for (int k = 0; k < 4; ++k) {
                        int nx = x + dx[k];
                        int ny = y + dy[k];

                        if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
                            if (g[nx][ny] == '1' && !visited[nx][ny]) {
                                visited[nx][ny] = true;
                                q.push({nx, ny});
                                cur.push_back({nx, ny});
                            } else if (g[nx][ny] == '0') {
                                breaks.insert({nx, ny});
                            }
                        }
                    }
                }

                // 更新最小敲碎数
                if (breaks.size() < minks) {
                    minks = breaks.size();
                }
            }
        }
    }

    return minks;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    cin >> n >> m;
    vector<string> g(n);
    for (int i = 0; i < n; ++i) {
        cin >> g[i];
    }

    cout << mink(n, m, g) << endl;

    return 0;
}

D.字符串里串

定义字符串 s 的可爱度 k 为这样的一个最大整数,使得存在长度为 k 的连续子串 a、长度为 k 的不连续子序列 b,满足 a=b。特别地,若不存在符合要求的 a,b,则可爱度为 0。
现在,对于给定的字符串 s,求解其可爱度。

利用一个 26*x 大小的二维数组来记录每个字母的出现位置。

我们二分可能出现的最大可爱度,对于每个mid,如果存在这个长度的子串,他的第一个字母在子串前面存在(不是这个字母第一次出现的位置)或者最后一个字符在子串之后存在(不是这个字母最后依次出现的位置)。那么就记录为true。继续扩大范围。反之缩小。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
typedef pair<int, int> PII;
const int N = 2e5 + 7;
const int inf = LLONG_MAX / 10;
const int mod = 998244353;
// const int mod = 1e9 + 7;
#define x first
#define y second
//二分暴龍龍
vector<vector<int>>a(26);
void miaojiachun()
{
    int n;
    cin>>n;
    string s;
    cin>>s;
    s=" "+s;
    for(int i=1;i<=n;i++){
        a[s[i]-'a'].push_back(i);
    }
    int l=0,r=n;
    int ans=0;
    while(l<=r){
        int mid=(l+r)/2;
        bool found=false;
        for(int i=1;i<=n-mid+1;i++){
            int tou=i,wei=i+mid-1;
            int t1=s[tou]-'a',w1=s[wei]-'a';
            if(a[t1].size()!=0 and a[t1][0]<tou){
                found=true;
                break;
            }if(a[w1].size()!=0 and a[w1][a[w1].size()-1]>wei){
                found=true;
                break;
            }
        }
        if(found){
            ans=mid;
            l=mid+1;
        }else{
            r=mid-1;
        }
    }
    cout<<ans<<endl;
}
signed main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int ING = 1;
    // cin >> ING;
    while (ING--)
    {
        miaojiachun();
    }
    return 0;
}

H.一起画很大的圆!

在二维平面中划定一个矩形区域,要求找道三个点,这三个点所确定的圆的半径最大。

本以为是三分。结果是规律,赛时按照规律题做。要么不对,要么超时,没比过大一的。屋里哇啦。

三个不共线的点确定一个圆。

如果这三个点越接近一条直线,这个圆最大。

那么我们需要在边界上找三个点使得最接近一条直线,猜一下有一个点会在边角,那剩下的点就不难确定了。

横着可以找到一个答案是 (a,d−1),(b,d),(b−1,d) ,但如果 d−c>b−a 的话,就应该竖着找。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
typedef pair<int, int> PII;
const int N = 2e5 + 7;
const int inf = LLONG_MAX / 10;
const int mod = 998244353;
// const int mod = 1e9 + 7;
#define x first
#define y second
//二分暴龍龍

void miaojiachun()
{
    int a,b,c,d;
    cin>>a>>b>>c>>d;
    vector<pair<int,int>>ans;
    int x=b-a;
    int y=d-c;
    if(x>y){
        ans.push_back({a,d-1});
        ans.push_back({b,d});
        ans.push_back({b-1,d});
    }else{
        ans.push_back({b,d});
        ans.push_back({b,d-1});
        ans.push_back({b-1,c});
    }
    for(auto&[x,y]:ans){
        cout<<x<<" "<<y<<endl;
    }
}
signed main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int ING = 1;
    cin >> ING;
    while (ING--)
    {
        miaojiachun();
    }
    return 0;
}
posted @ 2025-01-26 12:45  miao-jc  阅读(22)  评论(0)    收藏  举报