【1】重刷+补题打卡

A.篮球比赛

链接: A
心理路程:第一时间是推规律,30s过后感觉是斐波那契,但是不是很相信自己,就由往下推一个数,得出规律, 原来是与奇偶性相关;`

#include <iostream>
using namespace std;
int main(){
	int t ;cin>>t;
	while(t--){
		int n;
		cin>>n;
		if(n==1) cout<<0<<endl;
		else if(n%2==0){
			cout<<n-1<<endl;
		} else cout<<n<<endl;
	}
	return 0;
} 

B.string

链接: B
心理路程:看到英文题不是很想读,但是没办法,总要跳出舒适圈,读完立马感觉是string字典对比,但不是很自信,把样例全都粘贴补上,全部对上才敢交

#include <iostream>
#include <cstring>
using namespace std;
void slove(){
	string a,b;
	cin>>a>>b;
	if(a==b) cout<<a<<'='<<b<<endl;
	else if(a<b) cout<<a<<'<'<<b<<endl;
	else cout<<a<<'>'<<b<<endl;
}
int main(){
	slove();
	return 0;
} 

c.二分

链接: 二分板子link
链接: C题目
心理路程:跟着榜打,但是一直没出,当时很焦急,感觉不应该这样啊,然后感觉板子写错了,de很长时间,但是一直没找出来;
收获:忘是固然,多看多练多写就行,要精确板子;

#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll p=1e9+7; 
ll a,b,x;
ll getN(ll t){
	ll cc=0;
	while(t){
		cc++;
		t/=10;
	} return cc;
}
void slove(){
	cin>>a>>b>>x;
	ll l=0,r=1e9;
	//没有l=1; 
	while(l<r){
		ll mid=(l+r+1)>>1;
		if(a*mid+b*getN(mid)<=x){
			l=mid;
		} else r=mid-1;
	} cout<<l<<endl;
}

int main(){
	slove();
	return 0;
}

做的时候重看下范围,x是1e18,于是就让r=1e18,l=1了,这个l取错了
该l=0,然后又wa,仔细读题,商店最多卖出1e9个,所以要写为 r=1e9
读题细心很重要

D.打篮球

链接: D
心理路程:第一眼,飘过,没看到连续观看,因为焦急,敲完直接交了,wa。然后再看题,想是前缀和,是没错,但是我的想法是4个单层for循环解决,很显然第一个样例跑出来就超时了;
赛后思考:很明显,是把问题想复杂了,前缀和只加上下标为0的即可。

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=2e5+9;
ll sum[N],a[N];
void slove(){
	ll n,m;cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	} 
	ll x;
	ll ans=0;
	for(int i=1;i<=n;i++){
		cin>>x;
		if(x) ans+=a[i],sum[i]=sum[i-1];
		else sum[i]=sum[i-1]+a[i];
	}
	ll ss=0;
	//cout<<ans<<endl;
	for(int i=m;i<=n;i++){
		ss=max(ss,sum[i]-sum[i-m]);
		//cout<<ss<<endl;
	} cout<<ss+ans<<endl;
}

int main(){
	slove();
	return 0;
}

E.鸡哥雕像

链接: E
心理路程:第一次写的时候感觉是前缀乘,于是就写了下来,但是果不其然,wa,然后再在乘的地方全部取mod,但是样例没过,于是又思考,前缀和的时候大于mod的取mod,细想,存在漏洞,之后不知道怎么解决,很焦急

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll N=2e5,p=998244353;
ll sum[N],a[N],ss[N];
void slove(){
	ll n; cin>>n;
	sum[0]=1;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		sum[i]=sum[i-1]*a[i];
		if(sum[i]>p) sum[i]%=p;
	}
	reverse(a+1,a+n+1);
	ss[0]=1;
	for(int i=1;i<=n;i++){
	//	cout<<a[i]<<endl;
		ss[i]=ss[i-1]*a[i];
		if(ss[i]>p) ss[i]%=p;
	}
	for(int i=1;i<=n;i++){
		cout<<(sum[i-1]*ss[n-i])%p<<' ';
	}
}

int main(){
	slove();
	return 0;
}

F.除二排序

链接: F
心理路程:这题好像没时间看,晃晃而过
赛后补题:思考过优先队列,不是很行,在思考存入set,也存在矛盾,
关键在于这个数是否有,想到了标记;

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
void slove(){
	ll n,x; cin>>n;
	vector<bool>bj(n+1,0),aa(n+1,1);
	bj[0]=1;
	for(int i=1;i<=n;i++){
		cin>>x;
		if(x<=n&&!bj[x]) bj[x]=1;
		else {
			while(x){
				x/=2;
				if(x!=0&&x<=n&&!bj[x]) {
					bj[x]=1;
					break;
				}
			}
		}
	} 
	if(bj==aa) puts("YES");
	else puts("NO");
}

int main(){
	ll t; cin>>t;
	while(t--)
	slove();
	return 0;
}

G.01字符

链接: G
心理路程: 第一眼,这题好熟悉,是不是最近写的一题?细看不是,硬是看了半天没敢写;
赛后补题:这题我不是很会,学习了一些大佬的前缀和思想,才a,这里的对应关系其实很好,把0看成-1,前缀和为0的则满足区间要求,求长即可

错误代码:tle,很显然暴力是不行的

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
ll sum[100500];
void slove(){
	ll n; cin>>n;
	string s; cin>>s;
	for(int i=0;i<n;i++){
		if(s[i]=='0') sum[i+1]=sum[i]-1;
		else sum[i+1]=sum[i]+1;
	}
	ll ans=0;
	for(ll i=1;i<=n;i++){
		for(ll j=i;j<=n;j++){
			if(sum[j]-sum[i-1]==0){
				ans=max(ans,j-i+1);
			}
		}		
	} cout<<ans<<endl;
}

int main(){
	//ll t; cin>>t;
	slove();
	return 0;
}

思考片刻,加个map做下标,前缀和为0的时候就标记下,一个for就以了

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
typedef long long ll;
ll n;
//const int N=2e5+9;
//const ll p=998244353;
void slove(){
	ll n;cin>>n;
	ll ans=0,sum=0; 
	vector<char>s(n+1);
	map<ll,ll>mp;
	for(ll i=1;i<=n;i++){
		cin>>s[i];
		if(s[i]=='0'){
			sum+=-1; 
		}else sum+=1;
		if(sum!=0&&!mp[sum]) mp[sum]=i;
		else {
			ans=max(ans,i-mp[sum]);
			//cout<<i-mp[sum]<<endl;
		}
	} cout<<ans<<endl;
}
int main(){
	 slove();
	return 0;
} 

H.正负数

链接: H
赛后补题:把问题简单话就行了,找到特征关系,正负性,全局关系,找到符合要求的负数区间,正数区间就可以出来了

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
typedef long long ll;
ll n;
void slove(){
	ll n,x; cin>>n;
	map<ll,ll>mp;
	ll tt=1,ans=0;
	mp[-1]=1;//本身也是 
	for(int i=1;i<=n;i++){
		cin>>x;
		if(x<0) tt*=-1;
		ans+=mp[tt];//巧妙的解决了配对区间
		mp[tt*-1]++;//为下次相加铺垫 
	} cout<<ans<<' '<<(n*(n+1))/2-ans;
}
int main(){
	 slove();
	return 0;
} 

I.小dp

链接: I
赛后补题:说实话,本来就很恐惧dp的,自身对其的掌握不是很好,但是要走出舒适圈,就要不断向前。本身,我自己思考后发现了倍数关系,感觉不用dp,从暴力,前缀和,到出现【1,5】时,而基数是5该怎么办?参考了大佬们的dp思路,一个做长度,一个做基数;最后勉强a出

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
typedef long long ll;
const ll N=1e9+7;
ll dp[2500][2500];
void slove(){
	 ll n,m; cin>>n>>m;
	 for(ll i=1;i<=n;i++) dp[1][i]=1;//初始话 
	 for(ll i=2;i<=m;i++){ //长度 
	 	for(ll j=1;j<=n;j++) //基数
		 for(ll k=1;k*j<=n;k++) //倍数
		 	dp[i][j]=(dp[i][j]+dp[i-1][j*k])%N;
	 }
	 ll ans=0;
	 for(int i=1;i<=n;i++){
	 	ans+=dp[m][i];
	 	if(ans>=N) ans%=N;
	 }  cout<<ans;
}
int main(){
	 slove();
	return 0;
} 

可能真的很菜吧,补题的同时又过了一遍,感觉有些还没有吃透,come on!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值