2025牛客寒假算法基础集训营2 个人题解
#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 ;
}
解题思路
#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 ;
}
解题思路
题目要求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 ;
}
解题思路
一开始卡了很久,以为是精度问题,写了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 ;
}
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 ;
}
解题思路
大模拟,可以通过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 ;
}
解题思路
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 ;
}
解题思路
找一个连续子串,和一个子序列,满足要求,贪心的想,从左往右看,若第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 ;
}
解题思路
构造题,与D的想法类似,首先构造m部分,在字符串右边循环插入a-z,此时左端部分只能插入a-z这26种字母,因此无解条件为n-m>26 || n==m
因此统一构造方法,取(n-m)个字母节的循环,详细可以见官方题解的图
#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 ;
}
解题思路
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 ;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战