2025牛客寒假算法基础集训营2 个人题解

2025牛客寒假算法基础集训营2 个人题解

A.一起奏响历史之音!

#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
void solve(){
	bool flag=false;
	for(int i=1;i<=7;i++){
		int x;cin>>x;
		if(x!=1 && x!=2 && x!=3 && x!=5 && x!=6){
			flag=true;
		}
	}
	if(flag) cout<<"NO"<<endl;
	else cout<<"YES"<<endl;

}
int main(){
	std::ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	int T=1;
	while(T--) solve();
	return 0;
}

B.能去你家蹭口饭吃吗

解题思路

  • 发现答案就是中位数
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N=5e5+10;
int a[N];
void solve(){
	int n;cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	sort(a+1,a+n+1);
	int ans=n/2+1;
	cout<<a[ans]-1<<endl;
}
signed main(){
	std::ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	int T=1;
	while(T--) solve();
	return 0;
}

F.一起找神秘的数!

解题思路

  • 题目要求x+y = x&y + x|y + x^y,容易发现当某一二进制位相同,即同时为0或者同时为1时满足要求,则答案为区间长度
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
void solve(){
	int l,r;cin>>l>>r;
	int ans=r-l+1;
	cout<<ans<<endl;

}
signed main(){
	std::ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	int T;cin>>T;
	while(T--) solve();
	return 0;
}

G. 一起铸最好的剑!

解题思路

  • 一开始卡了很久,以为是精度问题,写了python都没过
  • 观察题目范围,n最大为1e9,容易知道答案次数不会很大,直接枚举即可
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define double long double
using namespace std;
void solve(){
	int n,m;cin>>n>>m;
	if(m==1){
		cout<<1<<endl;
		return;
	}
	int k=0;
	for(int i=1;i<=100;i++){
		int t=powl(m,i);
		if(t>=n){
			k=i;
			break;
		}
	}
	if(k==1){
		cout<<1<<endl;
		return;
	}
//	cout<<" "<<k<<endl;
	int t1=powl(m,k-1);
	int t2=powl(m,k);
	int ans=0;
	if(llabs(t1-n)<=llabs(t2-n)){
		ans=k-1;
	}
	else ans=k;
	cout<<ans<<endl;
}
signed main(){
	std::ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	int T;cin>>T;
	while(T--) solve();
	return 0;
}

J. 数据时间?

解题思路

  • 大模拟,可以通过substr函数得到时间,判断时间可以通过都转化为秒数进行比较,这样便于写代码
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
int t1st,t1ed,_t1st,_t1ed;
int t2st,t2ed;
int t3st,t3ed,_t3st,_t3ed;
int calc(int h,int m,int s){
	return 3600*h+60*m+s;
}
bool check1(int T){
	if(t1st<=T && T<=t1ed) return true;
	if(_t1st<=T && T<=_t1ed) return true;
	return false;
}
bool check2(int T){
	if(t2st<=T && T<=t2ed) return true;
	return false;
}
bool check3(int T){
	if(t3st<=T && T<=t3ed) return true;
	if(_t3st<=T && T<=_t3ed) return true;
	return false;
}
void solve(){
	t1st=calc(7,0,0),t1ed=calc(9,0,0);
    _t1st=calc(18,0,0),_t1ed=calc(20,0,0);
    t2st=calc(11,0,0),t2ed=calc(13,0,0);
    t3st=calc(22,0,0),t3ed=calc(23,59,59);
    _t3st=calc(0,0,0),_t3ed=calc(1,0,0);
	int n,Y,M;cin>>n>>Y>>M;
	set<string> st1,st2,st3;
	for(int i=1;i<=n;i++){
		string s1,s2,s3;
		cin>>s1>>s2>>s3;
		int y=stoi(s2.substr(0,4));
        int m=stoi(s2.substr(5,2));
        if(m!=M || y!=Y) continue;
        int _hour=stoi(s3.substr(0,2));
        int _minn=stoi(s3.substr(3,2));
        int _second=stoi(s3.substr(6,2));
        int _time=calc(_hour,_minn,_second);
        
        if(check1(_time)){
        	st1.insert(s1);
        }
        if(check2(_time)){
        	st2.insert(s1);
        }
        if(check3(_time)){
        	st3.insert(s1);
        }
	}
	cout<<st1.size()<<" "<<st2.size()<<" "<<st3.size()<<endl;

}
int main(){
	std::ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	int T=1;
	while(T--) solve();
	return 0;
}

K.可以分开吗?

解题思路

  • dfs,每次搜索一个联通块时,要注意将周围都白色方块计数,并且打上标记,标记的方法可以用map或者set记录,亲测重新再开一个vis数组每次清空会超时
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N=510;
typedef pair<int,int> PII;
char g[N][N];
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
bool vis[N][N];
bool vis2[N][N];
int n,m;
int ans=1e8;
int cnt=0;
void dfs(int x,int y,map<PII,int> &mp){
	vis[x][y]=1;
	for(int i=0;i<4;i++){
		int tx=x+dx[i];
		int ty=y+dy[i];
		if(tx<1 || tx>n || ty<1 || ty>m) continue;
		if(g[tx][ty]=='0'){
			if(!mp[{tx,ty}]){
				cnt++;
				mp[{tx,ty}]=1;
			}
			continue;
		}
		if(vis[tx][ty]) continue;
		dfs(tx,ty,mp);
	}
}
void init(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			vis2[i][j]=0;
		}
	}
}
void solve(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>g[i][j];
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(g[i][j]=='1' && !vis[i][j]){
				map<PII,int> mp;
				cnt=0;
				dfs(i,j,mp);
				ans=min(ans,cnt);
			}
		}
	}
	cout<<ans<<endl;
}
signed main(){
	std::ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	int T=1;
	while(T--) solve();
	return 0;
}

D. 字符串里串

解题思路

  • 找一个连续子串,和一个子序列,满足要求,贪心的想,从左往右看,若第i位字母在[i+1,n]中出现,则可以将[1,i]子串是满足条件的(我们可以将[1,i-1]作为一部分,后面出现的相同的字母作为第二部分,构成子序列),从右向左同理。
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
void solve(){
	int n;cin>>n;
	string s;cin>>s;
	s=" "+s;
	map<char,int> mp;
 	int ans=0;
	for(int i=n;i>=2;i--){
		if(mp[s[i]]) ans=max(ans,i);
		else mp[s[i]]=1;
	}
	map<char,int> mpp;
	for(int i=1;i<=n-1;i++){
		if(mpp[s[i]]) ans=max(ans,n-i+1);
		else mpp[s[i]]=1;
	}
	cout<<ans<<endl;
}
int main(){
	std::ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	int T=1;
	while(T--) solve();
	return 0;
}

C. 字符串外串

解题思路

  • 构造题,与D的想法类似,首先构造m部分,在字符串右边循环插入a-z,此时左端部分只能插入a-z这26种字母,因此无解条件为n-m>26 || n==m
  • 因此统一构造方法,取(n-m)个字母节的循环,详细可以见官方题解的图
  • image-20250125131018056
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
void solve(){
	int n,m;cin>>n>>m;
	if(n==m || n-m>26){
		cout<<"NO"<<endl;
		return;
	}
	string s;
	cout<<"YES"<<endl;
	for(int i=0;i<n;i++){
		char ch='a'+i%(n-m);
		s+=ch;
	}
	cout<<s<<endl;

}
int main(){
	std::ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	int T;cin>>T;
	while(T--) solve();
	return 0;
}

H.一起画很大的圆!

解题思路

  • guess题,猜错了,鏖战两小时未能战胜
  • 外接圆半径最大,想到尽量让三个点接近一条直线,这样的话半径最大,则可以有两种方法构造,(b,d),(b-1,d),(a,d-1)或(a,d),(a,d-1),(a+1,c)比较一下即可
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define double long double
using namespace std;
typedef pair<int,int> PII;

double distance(double x1,double y1,double x2,double y2){
    double dx=x2-x1;
    double dy=y2-y1;
    return sqrt(dx*dx+dy*dy);
}
double radius(double x1, double y1,
              double x2, double y2,
              double x3, double y3)
{
    double a=distance(x1,y1,x2,y2);
    double b=distance(x2,y2,x3,y3);
    double c=distance(x3,y3,x1,y1);
    double s=abs(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2))/2;
    double r=(a*b*c)/(4.0*s);
    return r;
}

void solve(){
	int a,b,c,d;cin>>a>>b>>c>>d;
	PII ans[4];
	int x1,y1,x2,y2,x3,y3;
	double maxn=0;
	double r=0;
	
	x1=b,y1=d;
	x2=b-1,y2=d;
	x3=a,y3=d-1;
	r=radius(x1,y1,x2,y2,x3,y3);
	if(r>maxn){
		maxn=r;
		ans[1]={x1,y1};
		ans[2]={x2,y2};
		ans[3]={x3,y3};
	}
	
	x1=a,y1=d;
	x2=a,y2=d-1;
	x3=a+1,y3=c;
	r=radius(x1,y1,x2,y2,x3,y3);
	if(r>maxn){
		maxn=r;
		ans[1]={x1,y1};
		ans[2]={x2,y2};
		ans[3]={x3,y3};
	}

	for(int i=1;i<=3;i++){
		cout<<ans[i].first<<" "<<ans[i].second<<endl;
	}
}
signed main(){
	std::ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	int T;cin>>T;
	while(T--) solve();
	return 0;
}

posted @   Persona_owl  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示