牛客白月赛17【题解】

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

小sun的假期【区间合并】

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
int n,m;
vector< pair<int,int> >ve,ans;
int main(void)
{
    
    
	cin>>n>>m;
	while(m--)
	{
    
    
		int l,r; cin>>l>>r;
		ve.push_back({
    
    l,r});
	}
	sort(ve.begin(),ve.end());
	int l=ve[0].first,r=ve[0].second;
	for(int i=1;i<ve.size();i++)
	{
    
    
		int j=i,flag=0,temp=0;
		while(j<ve.size()&&ve[j].first<=r) flag=1,temp=max(temp,ve[j].second),j++;
		if(flag) r=max(r,temp),i=j-1;
		else
		{
    
    
			ans.push_back({
    
    l,r});
			l=ve[i].first,r=ve[i].second;
		}
	}
	ans.push_back({
    
    l,r});
	int sum=0;
	if(ans.size()) sum=max(sum,ans[0].first-1);
	for(int i=1;i<ans.size();i++) 
		sum=max(sum,ans[i].first-ans[i-1].second-1);
	sum=max(sum,n-ans[ans.size()-1].second);
	cout<<sum;
	return 0;
}

扫雷【模拟】

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int n,m;
string s[N];
int solve(int x,int y)
{
    
    
	int cnt=0;
	for(int i=x-1;i<=x+1;i++)
		for(int j=y-1;j<=y+1;j++)
		{
    
    
			if(i==x&&y==j) continue;
			if(i<0||i>=n||j<0||j>=m) continue;
			if(s[i][j]=='*') cnt++;
		}
	return cnt;
}
int main(void)
{
    
    
	cin>>n>>m;
	for(int i=0;i<n;i++) cin>>s[i];
	for(int i=0;i<n;i++)
	{
    
    
		for(int j=0;j<m;j++)
		{
    
    
			if(s[i][j]=='*') cout<<s[i][j];
			else cout<<solve(i,j);
		}
		puts("");
	}
	return 0;
}

异或和

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
int main(void)
{
    
    
	int n,x,sum=0; cin>>n;
	for(int i=0;i<n;i++) scanf("%d",&x),sum^=x;
	cout<<sum;
	return 0;
}

解密

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int k1,k2;
string s;
int main(void)
{
    
    
	cin>>k1>>k2>>s;
	for(int i=0;i<s.size();i++)
	{
    
    
		int w=tolower(s[i])-'a';
		for(int j=0;j<26;j++)
		{
    
    
			int sum=j*k1+k2;
			if(sum%26==w)
			{
    
    
				if(s[i]>='a') cout<<char(j+'a');
				else cout<<char('A'+j);
			}
		}
	}
	return 0;
}

图的遍历【思维 二分图】

在这里插入图片描述
首先最少的边必定是连通块的数量-1 我们知道奇环是一定可以所有的点都可以走的。二分图是没有奇环的。
如果它是一个二分图那么说明无奇环,则不能所有的点都走到,此时我们加一条边便可变成奇环,就可以了。

#include<bits/stdc++.h> 
using namespace std;
const int N=1e5+10;
vector<int>ve[N];
int st[N],n,m,flag=1,ans;
void dfs(int u,int c)
{
    
    
	st[u]=c;
	for(int i=0;i<ve[u].size();i++)
	{
    
    
		int j=ve[u][i];
		if(!st[j]) dfs(j,3-c);
		else if(st[j]==st[u]) flag=0;//不是一个二分图
	}
}
int main(void)
{
    
    
	cin>>n>>m;
	while(m--)
	{
    
    
		int a,b; cin>>a>>b;
		ve[a].push_back(b);
		ve[b].push_back(a);
	}
	for(int i=1;i<=n;i++)
	{
    
    
		if(!st[i])
		{
    
    
			dfs(i,1);
			ans++;
		}
	}
    cout<<ans-1+flag;
	return 0;
}

区间求和【莫队】

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL n,m,ans;
LL va[N],pos[N],cnt[N],anw[N];
struct node
{
    
    
	int l,r,id;
}Node[N];
bool cmp(node a,node b)
{
    
    
	if(pos[a.l]!=pos[b.l]) return pos[a.l]<pos[b.l];
	return a.r<b.r;
}
void add(int x)
{
    
    
	ans-=cnt[va[x]]*cnt[va[x]]*va[x];
	cnt[va[x]]+=1;
	ans+=cnt[va[x]]*cnt[va[x]]*va[x];
}
void sub(int x)
{
    
    
	ans-=cnt[va[x]]*cnt[va[x]]*va[x];
	cnt[va[x]]-=1;
	ans+=cnt[va[x]]*cnt[va[x]]*va[x];
}
int main(void)
{
    
    
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>va[i];
	int len=sqrt(n);//分块
	for(int i=1;i<=n;i++) pos[i]=i/len;//分快
	for(int i=1;i<=m;i++)
	{
    
    
		int l,r; cin>>l>>r;
		Node[i]={
    
    l,r,i};
	}
	sort(Node+1,Node+m+1,cmp);
	int l=1,r=0;
	for(int i=1;i<=m;i++)
	{
    
    
		while(Node[i].l<l) add(--l);
		while(Node[i].r>r) add(++r);
		while(Node[i].l>l) sub(l++);
		while(Node[i].r<r) sub(r--);
		anw[Node[i].id]=ans;
	}
	for(int i=1;i<=m;i++) cout<<anw[i]<<'\n';
	return 0;
}

坐电梯

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e6+10;
LL a[N],n,k;
int main(void)
{
    
    
	cin>>n>>k;
	for(int i=1;i<=n;i++) cin>>a[i];
	sort(a+1,a+n+1);
    if(a[n]>k) cout<<a[n]-1+a[n]-k;
    else cout<<k-1;
	return 0;
}

猜你喜欢

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