2020牛客寒假算法基础集训营第二场

A 做游戏 min(A,Y)+min(B,Z)+min(C,X)
B 排数字 61616161……,可以看出ans=min(cnt6-1,cnt1)
G 判正误 哈希,记得多取几个模数防止被卡。
D 数三角 枚举所有情况即可。500的O(n3)风险大,但这道题可以。听说能用极角排序,呸!我不会
E 做计数 我觉得挺简单的题。传送门

对所需满足的式子左右平方,就可以发现规律。只需找到小于等于n的平方数的因数数目之和即可。
AC代码

#include 
using namespace std;
int numyin(int x){
	int res=0;
	for(int i=1;i<x;i++){
		if((x*x)%i==0)
			res+=2; 
	}
	return  res+1;
}
int main(){
	int n;
	cin>>n;
	int fac=1,ans=0;
	while(fac*fac<=n){
		ans+=numyin(fac);
		fac++;
	}
	cout<<ans<<endl;
	return 0;       
}

F 拿物品
关键是方法,我们不妨设现在只有两组a1,b1,a2,b2,牛牛来选。结果无非是两种:牛牛选a1,牛可乐选b2;或者牛牛选a2,牛可乐选b1.差距分别为a1-b2,a2-b1.若要使第一种情况差距更大,即a1-b2>a2-b1 --> a1+b1>a2+b2; 即选总和更大的一组能得到更大的差距。由此我们得到了最优解的思路。
AC代码

#include 
#include 
#define  pd		pair
using namespace std;
vector<int> a,b;
vector<int> ans1,ans2;
int main(){
	int n;
	cin>>n;
	a.resize(n); b.resize(n);
	for(int i=0;i<n;i++)
		cin>>a[i];
	for(int i=0;i<n;i++)
		cin>>b[i];
	priority_queue<pd,vector<pd>,less<pd> >t;	//使用优先队列实现a+b由大到小排列并同时储存对应的序号。
	for(int i=0;i<n;i++){
		t.push(pair<int,int>(a[i]+b[i],i+1)); 
	}
	int fac=1;
	while(!t.empty()){
		auto temp=t.top();
		if(fac){ 	ans1.push_back(temp.second); fac=0;  t.pop(); }
		else{ ans2.push_back(temp.second); fac=1; t.pop(); 	} 
	}	//储存牛牛和牛可乐分别按最优解选的数的序号。
	for(int i=0;i<ans1.size();i++)
		cout<<ans1[i]<<' ';
    cout<<endl;
	for(int i=0;i<ans2.size();i++)
		cout<<ans2[i]<<' ';
	return 0;
}

C 算概率
首先还是要观察出是个DP才行。剩下的就是状态转移方程:f(i,j)表示前i道题中正确 j 道题的概率。所以f(i,j)=f(i-1,j)*p[i]+f(i-1,j-1)*(1-p[i])唯一需要注意的就是此处用了一个mod,细心就可以发现若a+b=1,则对于取法的(q+q1)%mod=1;
AC代码

#include 
const int N=2005,mod=1e9+7;
#define ll long long
using namespace std;
ll f[N][N],p[N];
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>p[i];
	f[1][0]=1+mod-p[1]; f[1][1]=p[1];
	for(int i=2;i<=n;i++){
		f[i][0]=(f[i-1][0]*(1+mod-p[i]))%mod;	
		for(int j=1;j<=i;j++){
			f[i][j]=((f[i-1][j]*(1+mod-p[i]))%mod+(f[i-1][j-1]*p[i])%mod)%mod;
		}
	}
	for(int i=0;i<=n;i++)
		cout<<f[n][i]<<' ';
	cout<<endl;
	return 0;
}

你可能感兴趣的:(牛客)