牛客白月赛19【题解】

https://ac.nowcoder.com/acm/contest/2272

「水」滔天巨浪【双指针】

在这里插入图片描述

#include<bits/stdc++.h> 
using namespace std;
const int N=1e5+10;
int a[N],n,ans; 
int main(void)
{
    
    
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++)
	{
    
    
		int j=i;
		while(j+1<=n&&a[j+1]-a[j]==1) j++;
		int len=j-i+1;
		if(len==n) ans=max(ans,len-1);//说明总的一整段都是连续的
		else ans=max(ans,len-2);
	}
	cout<<ans;
	return 0;
}

「木」迷雾森林【DP】

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=3010;
const int mod=2333;
int f[N][N],a[N][N],n,m;
int main(void)
{
    
    
	memset(a,0x3f,sizeof a);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++) scanf("%d",&a[i][j]);
	f[n][1]=1;
	for(int i=n;i>=1;i--)
	{
    
    
		for(int j=1;j<=m;j++)
		{
    
    
			if(a[i+1][j]==0) f[i][j]=(f[i][j]+f[i+1][j])%mod;
			if(a[i][j-1]==0) f[i][j]=(f[i][j]+f[i][j-1])%mod;
		}
	}
	cout<<f[1][m]<<endl;
	return 0; 
}

「土」秘法地震【前缀和】

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int n,m,k,cnt,s[N][N];
string a[N];
int main(void)
{
    
    
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++)
		for(int j=0;j<m;j++)
			s[i][j+1]=a[i][j]-'0';
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++) 
			s[i][j]+=s[i-1][j]+s[i][j-1]-s[i-1][j-1];
	for(int i=1;i+k-1<=n;i++)
	{
    
    
		for(int j=1;j+k-1<=m;j++)
		{
    
    
			int x=i,y=j;
			int xx=i+k-1,yy=j+k-1;
			int sum=s[xx][yy]-s[x-1][yy]-s[xx][y-1]+s[x-1][y-1];
			if(sum) cnt++;
		}
	}
	cout<<cnt;
	return 0;
}

「金」初心如金【思维】

在这里插入图片描述
思维题,题目输入的查询都是奇数。
故我们可以根据后面的数据来判断,如果后一个是偶数说明前面的结果是1,这样异或才会便偶数。
否则说明前面的结果为0,这样才是奇数。

#include<bits/stdc++.h>
using namespace std;
long long int n,x;
int main()
{
    
    
	scanf("%lld%lld",&n,&x);
	for(int i=2;i<=n;++i)
	{
    
    
		scanf("%lld",&x);
		printf((x&1)?"0\n":"1\n");
	}
	return 0;
}

「火」烈火燎原【思维】

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5+10;
LL d[N],n,ans;
int main()
{
    
    
	cin>>n;
	for(int i=1;i<=n-1;i++)
	{
    
    
		int a,b; cin>>a>>b;
		d[a]++,d[b]++;
	}
	for(int i=1;i<=n;i++)
	{
    
    
		ans+=(d[i]*(d[i]-1))/2;
	}
	cout<<ans;
	return 0;
}


「水」悠悠碧波【KMP】

在这里插入图片描述

#include<bits/stdc++.h> 
using namespace std;
const int N=1e6+10;
int ne[N],n;
int main(void)
{
    
    
	string s; cin>>s;
	n=s.size();
	s="0"+s;
	for(int i=2,j=0;i<=n;i++)
	{
    
    
		while(j&&s[i]!=s[j+1]) j=ne[j];
		if(s[i]==s[j+1]) j++;
		ne[i]=j;
	}
	set<int>st;
	for(int i=1;i<n;i++) st.insert(ne[i]);//将其除最后一个,所有的前后缀保存
	int step=ne[n];
	while(step)
	{
    
    
		if(st.find(step)!=st.end())//如果找到了相等的前后缀的大小。
		{
    
    
			cout<<s.substr(1,step);
			break;
		}else step=ne[step];
	}
	return 0;
}

「金」点石成金【二进制枚举】

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=110;
LL a[N],b[N],c[N],d[N],n;
int main(void)
{
    
    
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>a[i]>>b[i]>>c[i]>>d[i];
	LL ans=0;
	for(int i=0;i<(1<<n);i++)
	{
    
    
		LL sum1=0,sum2=0;
		for(int j=0;j<n;j++)
		{
    
    
			if(i>>j&1) 
			{
    
    
			    sum1+=a[j];
				sum2=max(sum2-b[j],0ll);
			}
			else
			{
    
    
				sum2+=c[j];
				sum1=max(sum1-d[j],0ll);
			}
		}
		ans=max(ans,sum1*sum2);
	}
	cout<<ans;
	return 0;
}

「土」巨石滚滚【贪心】

在这里插入图片描述
我们先按照 node.b-node.a 的从大到小排。

扫描二维码关注公众号,回复: 14141366 查看本文章
  • 如果 (node.b-node.a)>=0 说明我们是可以回血的,那么按照a.a<b.a 来排,先选消耗小的。
  • 如果 (node.b-node.a)<0 说明无论如何我们都是要掉血的,那么按照a.b>b.b 来排,先选回复大的。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
struct node
{
    
    
	int a,b,c;
}Node[N];
bool cmp1(node a,node b){
    
    return a.c>b.c;}
bool cmp2(node a,node b){
    
    return a.a<b.a;}
bool cmp3(node a,node b){
    
    return a.b>b.b;}
int main(void)
{
    
    
	int t; cin>>t;
	while(t--)
	{
    
    
		LL n,m; cin>>n>>m;
		LL k=0;
		for(int i=0;i<n;i++)
		{
    
    
			cin>>Node[i].a>>Node[i].b;
			Node[i].c=Node[i].b-Node[i].a;
			if(Node[i].c>0) k++;
		} 
		sort(Node,Node+n,cmp1);
		sort(Node,Node+k,cmp2);
		sort(Node+k,Node+n,cmp3);
		LL flag=1;
		for(int i=0;i<n;i++)
		{
    
    
			m-=Node[i].a;
			if(m<0) flag=0;
			m+=Node[i].b;
		}
		if(flag) puts("Yes");
		else puts("No");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_46527915/article/details/124549640