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;
}

浙公网安备 33010602011771号