牛客小白月赛59

比赛链接:https://ac.nowcoder.com/acm/contest/43844

A:我会开摆

思路:暴力枚举。我们只需要枚举这个点位的周围位置是否等于自己本身即可

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=10;
char a[N][N];

inline void solve(){
	for(int i=1;i<=4;i++)
		for(int j=1;j<=4;j++)
			cin>>a[i][j];
	bool ok=false;
	for(int i=1;i<=3;i++)
		for(int j=1;j<=3;j++)
			if(a[i][j]==a[i][j+1]&&a[i][j]==a[i+1][j+1]&&a[i][j]==a[i+1][j])
				ok=true;
	if(ok) cout<<"Yes\n";
	else cout<<"No\n";		
}

signed main(){
	int T;cin>>T;
	while(T--) solve();
}

B: 走廊的灯

思路:根据题意发现,第一种情况是字符串中不存在'1'的情况,第二种情况是字符串中不存在'0'的情况。所以直接暴力枚举统计两种情况的最大值,最终取最大值即可。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
char s[N];

inline void solve(){
	int n;cin>>n>>s+1;
	int res=0,cnt=0;
	for(int i=1;i<=n;i++){
		if(s[i]=='1') cnt=0;
		else cnt++,res=max(res,cnt);
	}
	cnt=0;
	for(int i=1;i<=n;i++){
		if(s[i]=='0') cnt=0;
		else cnt++,res=max(res,cnt);
	}
	cout<<res<<"\n";
}

int main(){
    int T;cin>>T;
    while(T--) solve();
}

C:输出练习

思路:这里选择用set容器进行存放数据。存放符合条件的数据,最后输出即可。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
int val=9223372036854775807;//2^64-1
int l,r,k;

inline void solve(){
	set<int>res;
	cin>>l>>r>>k;
	int t=1;
	if(l<=t and t<=r) res.insert(t);
	for(int i=1;i<64;i++){
		if(k==0 or t<=val/k){
			t*=k;
			if(l<=t and r>=t) res.insert(t);
		}
		else break;
	}
	if(res.size()){
		for(auto x:res) cout<<x<<" ";
	}
	else cout<<"None.";
	cout<<"\n";
}

signed main(){
	int T;cin>>T;
	while(T--) solve();
}

D:国际象棋

思路:模拟。对每一次落棋进行判断,如果达到连棋子数,输出棋子数。否则再判断下次落棋。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
int board[N][N]; // 0--空白格 1--黑棋子 2--白棋子
int cnt[N];
int n,m,k,t;
bool pd(int row,int col){//判断连棋子数
    int type=board[row][col];
    // up & down
    {
        int num1=0,num2=0;//num1:上边  num2:下边
        int i=row;
        while(i>=1&&board[i][col]==type) i--,num1++;
        i=row;
        while(i<=n&&board[i][col]==type) i++,num2++;
        if(num1+num2-1>=k) return true;
    }
    // left & right
    {
        int num1=0,num2=0;//num1:左边  num2:右边
        int i=col;
        while(i>=1&&board[row][i]==type) i--,num1++;
        i=col;
        while(i<=m&&board[row][i]==type) i++,num2++;
        if(num1+num2-1>=k) return true;
    }
    // (\)斜边
    {
        int num1=0,num2=0;//num1:左上  num2:右下
        int i=row,j=col;
        while(i>=1&&i<=n&&j>=1&&j<=m&&board[i][j]==type) i--,j--,num1++;
        i=row,j=col;
        while(i>=1&&i<=n&&j>=1&&j<=m&&board[i][j]==type) i++,j++,num2++;
        if(num1+num2-1>=k) return true;
    }
    //(/)斜边
    {
        int num1=0,num2=0;//num1:右上  num2:左下
        int i=row,j=col;
        while(i>=1&&i<=n&&j>=1&&j<=m&&board[i][j]==type) i--,j++,num1++;
        i=row,j=col;
        while(i>=1&&i<=n&&j>=1&&j<=m&&board[i][j]==type) i++,j--,num2++;
        if(num1+num2-1>=k) return true;
    }
    return false;
}

int main(){
    cin>>n>>m>>k>>t;
    for(int i=1;i<=t;i++){
        int col;cin>>col;
        int type;
        if(i&1) type=1;
        else type=2;
        int row=++cnt[col];//判断某列上第i行的棋子
        board[row][col]=type;
        if(pd(row,col)) {
            cout<<i<<endl;
            return 0;
        }
    }
}

E:弹珠碰撞

思路:经典模型:《碰撞==穿过》

 我们发现:这里的碰撞就可以理解为穿过,题意所说:碰撞后会停止一秒,那么这里可以理解为,穿过后增加一秒。

所以这个题,我们也是同样的处理方式。

至于停顿时间,例如下图绿球,停顿的时间等于右边红球的数量。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e6+10;
int n,m;
int d[N],p[N],dir[N];//dir:代表方向

inline void solve(){
	cin>>n>>m;
	for(int i=1;i<=m;i++) cin>>d[i];
	for(int i=1;i<=m;i++) cin>>p[i],dir[p[i]]=d[i]+1;//使1代表左边,2代表右边
//  1 <-------              2 ------->
	int l=0,r=0,ans=0;
	for(int i=1;i<=n;i++){
		if(dir[i]==0) continue;
		if(dir[i]==1) ans=max(ans,i+r);// <---------向左
		else r++;
	}
	for(int i=n;i>=1;i--){
		if(dir[i]==0) continue;
		if(dir[i]==2) ans=max(ans,n-i+1+l);// ------->向右
		else l++;
	}
	cout<<ans<<"\n";
}

signed main(){
	solve();
}

对于这道题的更好解释,可以看ygg的blog:https://zhuanlan.zhihu.com/p/578344284

F: 困难卷积

思路:这里有个 trick

若 ∑a=n ,则数组 a 中不同的不超过 sqrt(n) 个。因为1+2+3+..=n,相加的个数不会超过sqrt(n)个。(就不证明了)

题目有个限制: ∑ai,∑bi<=1e7。根据结论:∑ai,∑bi的时间复杂度为sqrt(1e7) x sqrt(1e7)=1e6,所以暴力并不会TLE。直接暴力即可。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e6+10;
int n;
int a[N],b[N];
map<int,int>mp1,mp2;

inline void solve(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i],mp1[a[i]]++;
	for(int i=1;i<=n;i++) cin>>b[i],mp2[b[i]]++;
	int ans=0;
	for(auto[lx,ly]:mp1){
		for(auto[rx,ry]:mp2){
			ans+=(int)(sqrt(abs(lx-rx)))*ly*ry;
		}
	}
	cout<<ans<<"\n";
}

signed main(){
	solve();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值