AtCoder Beginner Contest 172 A-E

A:模擬

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = 1e5+7;

int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	ll n;
  	cin>>n;
  	cout<<(n+n*n+n*n*n)<<endl;
	return 0;
}

B:直接比較。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = 2e5+7;

char a[M],b[M];
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	cin>>a>>b;
  	int n=strlen(a);
  	int nm=0;
  	for(int i=0;i<n;i++)
  	{
  		if(a[i]!=b[i])nm++;
	  }
	  cout<<nm<<endl;
	return 0;
}

C:枚舉a數組,快速找到最優的b數組的位置即可。

也可以雙指針搞。

#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 = 2e5+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;}
*/
ll a[M],b[M],sm[M];
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	int n,m,k;
  	cin>>n>>m>>k;
  	for(int i=1;i<=n;i++)cin>>a[i];
  	for(int i=1;i<=m;i++)cin>>b[i],sm[i]=sm[i-1]+b[i];
  	ll sa=0;
	  int mx=0;
	for(int i=0;i<=n;i++)
  	{
  		sa+=a[i];
  		if(sa>k)break;
  		int id=upper_bound(sm+1,sm+1+m,k-sa)-sm;
  		id--;
  		mx=max(mx,i+id);
	}
	cout<<mx<<endl;
	return 0;
}

D:

直接nlogn暴力即可。

#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 = 1e7+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;}
*/
ll nm[M];
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	int n;
  	cin>>n;
  	for(int i=1;i<=n;i++)
  		for(int j=1;j<=n/i;j++)
  			nm[i*j]++;
  	ll ans=0;
  	for(int i=1;i<=n;i++)
  		ans+=nm[i]*i;
	cout<<ans<<endl;
	return 0;
}

E:容斥+組合數

先把a數組固定:即A(n,m)從m種選n個進行全排列。

然後b數組選出n個數,求出使得第i個數不爲i的個數。再利用乘法原理即可求出結果。

難點在如何求出使從b數組選出n個數得第i個數不爲i的個數。

用容斥處理即可:

第i個數爲i的並集和。=   一個數不爲i - 兩個數不爲i + 3個數不爲i -……

然後用總排列減去這個就是從b數組選出n個數得第i個數不爲i的個數。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = 5e5+7;
const int mod=1e9+7;
ll qpow(ll a,ll b)
{
	ll ans=1;
	while(b)
	{
		if(b&1)ans=ans*a%mod;
		a=a*a%mod;
		b/=2;
	}
	return ans;
}

ll fac[M],inv[M];
ll f[M],dp[M];//錯排 
ll A(int n,int m){
	return fac[m]*inv[m-n]%mod;
}
ll C(int n,int m){
	return fac[m]*inv[n]%mod*inv[m-n]%mod;
}
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	int n,m,N=5e5;
  	cin>>n>>m;fac[0]=inv[0]=1;
	for(int i=1;i<=m;i++)fac[i]=fac[i-1]*i%mod,inv[i]=qpow(fac[i],mod-2);
	f[2]=1;for(int i=3;i<=m;i++)f[i]=(f[i-1]+f[i-2])*(i-1)%mod;
	ll ans=A(n,m);
	//n個位置不同 
	for(int i=1;i<=n;i++)//至少幾個位置相同
	{
	//	cout<< ans<<"  "<<i<<"  - "<<C(i,n)<<"  "<<A(n-i,m-i)<<endl;
		ll tp=C(i,n)*A(n-i,m-i)%mod;
		
		if(i&1)ans=(ans-tp+mod)%mod;
		else ans=(ans+tp)%mod;
	}
	cout<<ans*A(n,m)%mod<<endl;
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章