2020牛客暑期多校训练营(第七场) BDH

B:

n*m个口罩分成最少的组使得可以这样分配:

n个医院,每个医院m个口罩。

m个医院,每个医院n个口罩。

为了使得数量最少,每组的口罩尽可能要大。

假设n<m

n个医院,每个医院m个口罩,

我们最多可以让  m/n*m组有n个口罩(当前最大值)。

然后问题转化为了:

n个医院每个医院需要m%n个口罩

m%n个医院,每个医院需要n个口罩。

变化为了子问题,dfs下去即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt=1;
void init(){cnt=1,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
vector<int>v;
void gao(int n,int m)
{
	if(m==0)return ;
	for(int i=1;i<=n/m*m;i++)v.pb(m);
	//m个医院需要n%m,n%m个医院需要m,转化为子问题 
	gao(m,n%m);
}
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	int t;
  	cin>>t;
  	while(t--)
  	{
  		int n,m;
  		cin>>n>>m;
  		v.clear();
  		if(n<m)swap(n,m);
  		gao(n,m);
  		cout<<v.size()<<endl;
  		for(auto x:v)
  		cout<<x<<" ";
  		cout<<endl;
	}
	return 0;
}

D:

打表

H:

分析性质可知:

n=x*k

n=x*k+1;

n=1;

先考虑n=x*k的情况:

假设k>=2.

ans=n/2+n/3+……+n/k;

用整数分块即可。

n=x*k+1   ->  n-1=x*k;

一样处理。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt=1;
void init(){cnt=1,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
const int mod=1e9+7;
//n/2+n/3+n/4+……+n/K 
ll cal(ll n,ll k)
{
	ll ans=0;
	for(ll l=2,r;l<=k;l=r+1)
	{
		r=n/l?min(n/(n/l),k):k;
		ans=(ans+n/l*(r-l+1))%mod;
	}
	return ans;
}
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	ll N,k;
  	cin>>N>>k;
  	//n=x*k
  	ll ans=0;
 	
	cout<<(cal(N,k)+cal(N-1,k)+N+k-1)%mod<<endl;
	return 0;
}

 

©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页