牛客白月赛26【题解】

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

牛牛爱学习【二分】

在这里插入图片描述
二分,check函数类似于多路归并。

#include<bits/stdc++.h> 
using namespace std;
const int N=1e6+10;
typedef long long int LL;
LL a[N],n,m,s; 
priority_queue<int>heap,q1;
bool cmp(int a,int b){
    
    return a>b;}
bool check(LL x)
{
    
    
	LL sum=0;
	q1=heap;
	queue<int>q[x+10];
	while(q1.size())//按照分组分好
	{
    
    
		for(int i=1;i<=x;i++) 
			if(q1.size()) q[i].push(q1.top()),q1.pop();
	}
	for(int i=1;i<=x;i++)
	{
    
    
		int step=0;
		while(q[i].size())
		{
    
    
			int temp=q[i].front()-step; q[i].pop();
			if(temp<=0) break;
			sum+=temp;
			step++;
		}
	}
	return sum>=m;
}
int main(void)
{
    
    
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i],s+=a[i];
	for(int i=1;i<=n;i++) heap.push(a[i]);
	if(s<m) puts("-1");
	int l=1,r=n;
	while(l<r)
	{
    
    
		int mid=(l+r)>>1; 
		if(check(mid)) r=mid;
		else l=mid+1;
	}
	cout<<l;
	return 0;
}

牛牛爱数学【一元二次方程求根】

在这里插入图片描述
根据求根公式推即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
int main(void)
{
    
    
	LL t; cin>>t;
	while(t--)
	{
    
    
		LL a,b,c; cin>>a>>b>>c;
		if( (b*c)%a == 0 ) cout<<b*c/a<<'\n';
		else cout<<-1<<'\n';
	}
	return 0;
}

牛牛种花【树状数组】

在这里插入图片描述
求左下角,我们就先排序按照x排,再按照y排。离散化一下。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5*2+10;
struct node{
    
    int x,y,id;};
int tr[N],ans[N],n,m;
vector<node>ve;
vector<int>a;
bool cmp(node a,node b)
{
    
    
	if(a.x==b.x) return a.y<b.y;
	return a.x<b.x;
}
int lowbit(int x)
{
    
    
	return x&(-x);
}
void add(int x,int v)
{
    
    
	for(int i=x;i<N;i+=lowbit(i)) tr[i]+=v;
}
int query(int x)
{
    
    
	int sum=0;
	for(int i=x;i;i-=lowbit(i)) sum+=tr[i];
	return sum;
}
int main(void)
{
    
    
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
    
    
		int x,y; cin>>x>>y;
		ve.push_back({
    
    x,y,0});
		a.push_back(y);
	}
	for(int i=1;i<=m;i++)
	{
    
    
		int x,y; cin>>x>>y;
		ve.push_back({
    
    x,y,i});
		a.push_back(y);
	}
	sort(ve.begin(),ve.end(),cmp);
	sort(a.begin(),a.end());
	a.erase(unique(a.begin(),a.end()),a.end());
	for(int i=0;i<ve.size();i++)
	{
    
    
		int x=ve[i].x,y=ve[i].y,id=ve[i].id;
		int index=lower_bound(a.begin(),a.end(),y)-a.begin();
		if(id==0) add(index+1,1);
		else ans[id]=query(index+1);
	}
	for(int i=1;i<=m;i++) cout<<ans[i]<<endl;
	return 0;
}

失忆药水【思维】

失忆药水
题目的意思就是说不含奇数环。二分图是不含奇数环的。故就是减几条边使其是二分图。
二分图,故点平分。总的边数-二分图的边数就是答案。

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
LL n;
int main(void)
{
    
    
	while(cin>>n) 
	{
    
    
		LL l=n/2;
		LL r=n-n/2;
		cout<<n*(n-1)/2-l*r<<endl;
	}
	return 0;
}

牛牛走迷宫【bfs】

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=550;
string s[N];
int n,m,st[N][N];
int dx[4]={
    
    1,0,0,-1};
int dy[4]={
    
    0,-1,1,0};
string a="DLRU";
struct node
{
    
    
	string s;
	int x,y,step;
};
void bfs()
{
    
    
	queue<node>q; q.push({
    
    "",0,0,0});
	st[0][0]=1;
	while(q.size())
	{
    
    
		auto temp=q.front(); q.pop();
		int x=temp.x,y=temp.y,d=temp.step;
		string ss=temp.s;
		if(x==n-1&&y==m-1)
		{
    
    
			cout<<d<<endl<<ss<<endl;
			return ;
		}
		for(int i=0;i<4;i++)
		{
    
    
			int tempx=x+dx[i],tempy=y+dy[i];
			if(tempx<0||tempx>=n||tempy<0||tempy>=m) continue;
			if(s[tempx][tempy]=='1') continue;
			if(st[tempx][tempy]) continue;
			st[tempx][tempy]=1;
			q.push({
    
    ss+a[i],tempx,tempy,d+1});
		}
	}
}
int main(void)
{
    
    
	cin>>n>>m;
	for(int i=0;i<n;i++) cin>>s[i];
	bfs();
    if(!st[n-1][m-1]) cout<<-1;
	return 0;
}

牛牛爱几何【签到】

#include<bits/stdc++.h>
using namespace std;
const double pi=acos(-1);
int main(void)
{
    
    
	double x;
	while(cin>>x)
	{
    
    
		printf("%.6lf\n",pi*(x/2*x/2*2)-x*x);
	}
	return 0;
}

恶魔果实【dfs】

在这里插入图片描述
每一位dfs一下,看每一位有几种情况。然后乘法原理即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5+10;
vector<int>ve[N];
LL cnt=0,st[N];
void dfs(int u,int fa)
{
    
    
	cnt++;
    st[u]=1;
	for(int i=0;i<ve[u].size();i++)
	{
    
    
		int j=ve[u][i];
        if(st[j]) continue;
		dfs(j,u);
	}
}
int main(void)
{
    
    
	string s; cin>>s;
	int n; cin>>n;
	while(n--)
	{
    
    
		int a,b; cin>>a>>b;
		ve[a].push_back(b);
	}
	LL ans=1;
	for(int i=0;i<s.size();i++) 
	{
    
    
		cnt=0;
        memset(st,0,sizeof st);
		dfs(s[i]-'0',-1);
		ans=ans*cnt%(10007);
	}
	cout<<ans;
	return 0;
}

牛牛喜欢字符串【贪心】

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
int n,k;
int main(void)
{
    
    
	cin>>n>>k;
	string s; cin>>s;
	int ans=0;
	for(int i=0;i<k;i++)
	{
    
    
		int cnt[26]={
    
    0},temp=0;
		for(int j=i;j<n;j+=k) cnt[s[j]-'a']++;//统计所有字串该位置的字母出现的次数
		for(int j=0;j<26;j++) temp=max(temp,cnt[j]);//取次数最多的,让其他的字母变成该字母
		ans+=(n/k)-temp;
	}
	cout<<ans;
	return 0;
}

猜你喜欢

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