牛客小白月赛7题解

没想到身为菜鸟的我也能做7题,嘿嘿嘿

2018/10/9 填坑完毕hhh

A-送分题:https://www.nowcoder.com/acm/contest/190/A

思路:该题直接交会爆内存。。。观察(跑几组数据)发现只要n大于等于2018001就都为 20182017,其他的则为 n+2017

Code :

#include
using namespace std;

int main()
{
    long long n;
    cin >> n;
    if(n<20180001)	cout<

 

B-自杀游戏:https://www.nowcoder.com/acm/contest/190/B

思路:可以用dp来做,对于dp[i],只要它能够转移到必败的状态,那么dp[i]一定是必胜的,否则就是必败的

Code:

#include
using namespace std;

const int MAX_N=100005;
int a,b,n;
int dp[MAX_N];

int main()
{
	while(cin>>n>>a>>b){
		++a;	++b;
		dp[0]=-1;
		for(int i=1;i<=n;++i)
		{
			if(dp[i-1]==-1){
				dp[i]=1;
			}else{
				if(i=j&&dp[i-j]==-1){
						dp[i]=1;	break;
					}
				if(dp[i]!=1)	dp[i]=-1;
			}
		}
		if(dp[n]==1)	cout<<"Alice"<

 

C-谁是神枪手:https://www.nowcoder.com/acm/contest/190/C

思路:不难求出,对于A胜概率 Pa,B胜概率 Pb为

牛客小白月赛7题解_第1张图片

 B胜条件 Pb-Pa>0 最后可化为 (100-a)*b>100*a

那么平局时(100-a)*b=100*a

A胜:(100-a)*b<100*a

Code :

#include
using namespace std;
 
int a,b;
 
int main()
{
    while(cin>>a>>b){
        if((100-a)*b>100*a)  cout<<"CSL"<

 

D-明七暗七:https://www.nowcoder.com/acm/contest/190/D

思路:数位DP+二分。利用数位DP可以求出从1到n的满足条件的个数,而对于求具体的数字,则可以用二分查找来求解

dp[i][j][k]: 前i位余数为j,是否有7的个数

Code :
 

#include
#include
using namespace std;
typedef long long LL;

LL n,m;
int a[20];
LL dp[20][10][2];

LL Find(LL p);
LL DFS(int k,int mod,int boo,int bo);
int main()
{
	ios::sync_with_stdio(false);
	while(cin>>n>>m){
		memset(dp,-1,sizeof(dp));
		LL l=n,r=1e14,t=Find(n);
		while(l<=r){
			LL h=(l+r)/2;
			if(Find(h)-t>=m)	r=h-1;
			else	l=h+1;
		}
		cout<

 

E-Applese的超能力: https://www.nowcoder.com/acm/contest/190/E

思路:对于m个硬币可合成 1个硬币,最后要只剩一个硬币,由最后n=1个硬币往后推,n=1+(m-1)个硬币成立,再是1+(m-1)可当成1个硬币,则还需要6个硬币 n= 1+(m-1)+(m-1)也成立,则n=1+(m-1)*k时为Yes,否则为No

Code :

#include
using namespace std;

int n,m;

int main()
{
	while(cin>>n>>m){
		bool boo=false;
		if(n==1||m!=1&&(n-1)%(m-1)==0)	boo=true;
		if(boo)	cout<<"Yes"<

 

F-BFS:https://www.nowcoder.com/acm/contest/190/F

思路:真水题

Code:

#include
using namespace std;

string str;

int main()
{
	while(cin>>str){
		int len=str.size();
		int boo=-1;
		for(int i=0;i

 

G-CSL分苹果:https://www.nowcoder.com/acm/contest/190/G

思路:背包DP,dp[i]=1表示 背包中有 i质量的苹果。则对于每个苹果质量x, 若dp[i]=1,则dp[i+x]=1;最后查找离所有苹果质量和一半sum/2最近的dp[i]=1即可

Code :

#include
using namespace std;

const int MAX_N=100;
const int MAX_S=10005;
int n;
int dp[MAX_S];

int main()
{
	ios::sync_with_stdio(false);
	cin>>n;
	dp[0]=1;
	int sum=0;
	for(int i=1,x;i<=n;++i)
	{
		cin>>x;
		sum+=x;
		for(int j=MAX_S-x-1;j>=0;--j)
		{
			if(dp[j]){
				dp[j+x]=1;
			}
		}
	}
	int ans=0;
	for(int i=sum/2;i>=0;--i)
		if(dp[i]){
			ans=i;	break;
		}
	cout<

 

H-CSL的校园卡:https://www.nowcoder.com/acm/contest/190/H

思路:状态压缩DP+BFS

用dp[x1][y1][x2][y2][s]来表示两人分别在点 (x1,y1),(x2,y2)处走过的状态s时的所用时间,那么再用BFS来找到第一个满足条件的即可

Code:

#include
#include
using namespace std;
 
struct node{
    int x1,y1;
    int x2,y2;
    int t,s;
};
const int MAX_S=(1<<16)+5;
const int f[][2]={-1,0, 1,0, 0,-1, 0,1};
int n,m,ans,Sum;
string G[5];
bool boo[5][5][5][5][MAX_S];
 
void BFS(int x,int y);
int main()
{
    cin>>n>>m;
    int x0,y0;
    for(int i=0;i>G[i];
        for(int j=0;j Q;
    Q.push(node{x,y,x,y,1<<(x*4+y),0});
    boo[x][y][x][y][(1<<(x*4+y))]=1;
    while(!Q.empty()){
        int x1,y1,x2,y2;
        node u=Q.front();   Q.pop();
        for(int i=0;i<4;++i)
        {
            x1=u.x1+f[i][0];    y1=u.y1+f[i][1];
            int t1=1<<(x1*4+y1);
            if(x1>=0&&x1=0&&y1=0&&x2=0&&y2

 

I-新建 Microsoft Office Word 文档:https://www.nowcoder.com/acm/contest/190/I

思路:利用优先队列Q来维护最小值,同时用数组boo[]来对已有文档序列做标记即可

Code:

#include
#include
using namespace std;

const int MAX_N=100005;
int n,T;
string str;
priority_queue,greater > Q;
bool boo[MAX_N];

int main()
{
	cin>>T;
	n=0;
	int x;
	while(T--){
		cin>>str;
		if(str=="New"){
			if(!Q.empty()){
				cout<>x;
			if(boo[x]){
				boo[x]=false;
				Q.push(x);
				cout<<"Successful"<

 

J-方格填色:https://www.nowcoder.com/acm/contest/190/J

思路:状态压缩+矩阵快速幂

对于状态压缩方程易得转换方程

for(int i=2;i<=n;++i)
	for(int j=0;j<=s;++j)
		for(int k=0;k<=s;++k)
			if((j||k)&&!(j&k))	dp[i][j]=(dp[i][j]+dp[i-1][k])%MOD;

而对于转移方程可以用矩阵快速幂来优化,与骨牌覆盖类似https://blog.csdn.net/C_13579/article/details/82883625

Code :

#include
#include
using namespace std;
typedef long long LL;

const int MOD=1e9+7;
const int MAX_S=35;
struct Matrix{
	LL a[MAX_S][MAX_S];
	Matrix(){memset(a,0,sizeof(a));}
	Matrix operator*(const Matrix &A){
		Matrix res=Matrix();
		for(int k=0;k>m>>n){
		int s=(1<>=1;
		}
		LL res=0;
		for(int i=0;i<=s;++i)
			for(int j=0;j<=s;++j)
				res=(res+ans.a[i][j])%MOD;
		cout<

 

你可能感兴趣的:(DP,模拟,牛客,概率论,优先队列)