牛客2021暑假多校联赛第一场补题

A题:

题意: 两人博弈,每次一个人从一堆中拿 k 个,同时从另一堆拿 k * s(s >= 0) 个,问谁先不能拿。

10000 组数据,N <= 5000

解题思路:暴力模拟  推理得:A一次能直接拿完A赢 拿不完B赢

代码:

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define N 5010
bool ans[N][N];

void pre_work(){
	//赋初值
	ans[0][0]=0;
	//穷举   一次能拿完的话A赢 不然B赢
	for(int i=0;i<=5000;i++){
		for(int j=0;j<=5000;j++){
			//已经被赋值 跳过 
			if(ans[i][j]==1)continue;
			//一堆取k个 另一堆取k*l 穷举
			for(int k=1;k+i<=5000;k++){
				for(int l=0;l*k+j<=5000;l++){
					ans[k+i][l*k+j]=1;
				}
			}
			//从第二堆取k个  从第一堆取k*l个
			for(int k=1;k+j<=5000;k++){
				for(int l=0;l*k+i<=5000;l++){
					ans[l*k+i][k+j]=1;
				}
			} 
		}
	} 
} 

int main(){
	pre_work();
	int t;
	cin>>t;
	while(t--){
		int n,m;
		cin>>n>>m;
		
		if(ans[n][m]==1)cout<<"Alice"<

B题:球卡在了梯形内,求卡住的高度是多少?

思路:数学推理,将梯形补成三角形,根据两次相似求得高度;

牛客2021暑假多校联赛第一场补题_第1张图片

代码:

#include 
#include 
#include 
#include 
using namespace std;
#define eps 1e-7;

int main(){
	double a,r,b,h,x,l,j;
	cin>>r>>a>>b>>h;
	if(b>2*r){
		//掉下去
		cout<<"Drop"<

D:题意:给出一个 n*n 的 01 矩阵,要用一个 1*m 的矩阵去覆盖一段 0,求方案数。

解题思路:1)将两个字符数组储存,利用kmp算法进行匹配,累加每一行的答案;

  1. 直接暴力模拟

代码:

KMP算法:

#include
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
char str[maxn],mo[maxn];
int Next[maxn];

void getNext(){
    Next[0]=-1;
    int len=strlen(mo),k=-1;
    for(int i=1;i-1&&mo[k+1]!=mo[i])k=Next[k];
        if(mo[k+1]==mo[i])k++;
        Next[i]=k;
    }
}
int Kmp(){
    getNext();
    int len1=strlen(str),len2=strlen(mo),k=-1,ans=0;
    for(int i=0;i-1&&mo[k+1]!=str[i])k=Next[k];
        if(mo[k+1]==str[i])k++;
        if(k==len2-1){
            k=Next[k];
            ans++;
        }
    }
    return ans;
}

char M[2005][2005];
int main(){
	int n,m;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%s",&M[i]);
	}
	int ans=0;
	scanf("%s",&M[0]);
	for(int i=0;i

暴力模拟:

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

int main(){
	int n,m;
	cin>>n>>m;
	ll ans=0;
	for(int i=0;i>s;
		for(int j=0;j

F题:

题意:定义一个自然数是 3-friendly 的,如果它存在一个子串(允许前导0)是 3 的倍数。多组数据,求 L~R 中 3-friendly 的数的个数。

解题思路:推理得:三位数及以上一定是,个位数打表,两位数暴力,利用前缀和速度求解。

代码:

#include 
using namespace std;
typedef long long ll;
ll dp[105]={0,0,0,1,1,1,2,2,2,3}; //前缀和数组  个位数直接打表 
ll t,lef,rig;

ll ans(ll x){
	if(x<=99) return dp[x];
	//推理得  三位数及以上 一定满足条件  返回个数加之前的 
	else return x-99+dp[99];
}

int main(){
	for(int i=10;i<=99;i++){
		if(i%10%3==0||i/10%3==0||i%3==0){
			//判断是否满足条件   个位数 十位数  整体 
			dp[i]=dp[i-1]+1;
		}else{
			dp[i]=dp[i-1];
		}		
	}
	cin>>t;
	while(t--){
		cin>>lef>>rig;
		cout<

你可能感兴趣的:(c++)