牛客白月赛32题解

Posted 辉小歌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客白月赛32题解相关的知识,希望对你有一定的参考价值。

https://ac.nowcoder.com/acm/contest/11163#question

目录

拼三角【枚举】

#include<bits/stdc++.h> 
using namespace std;
int a[15],st[15],flag;
bool check(vector<int> ve)

	sort(ve.begin(),ve.end());
	return ve[0]+ve[1]>ve[2];

void dfs(int index)

	if(index==3)
	
		vector<int>ve1,ve2;
		for(int i=0;i<6;i++)
			if(st[i]) ve1.push_back(a[i]);
			else ve2.push_back(a[i]);
		if(check(ve1)&&check(ve2)) flag=1;
		return;
	
	for(int i=0;i<6;i++)
	
		if(!st[i]) 
		
			st[i]=1;
			dfs(index+1);
			st[i]=0;
		
	

int main(void)

	int t; cin>>t;
	while(t--) 
	
		for(int i=0;i<6;i++) cin>>a[i];
		flag=0;
		memset(st,0,sizeof st);
		dfs(0);
		if(flag) puts("Yes");
		else puts("No");
	
	return 0;

用全排列更简单。

消减整数【思维】


转化成二进制后一定是一连串的,中间不能有0。往前进位就行。

#include<bits/stdc++.h> 
using namespace std;

int main(void)

	int t; cin>>t;
	while(t--) 
	
		int n; cin>>n;
		vector<int>ve;
		int cnt=0;
		ve.push_back(n);
		for(int i=0;i<32;i++) ve.push_back(0); 
		for(int i=0;i<32;i++)
			if(ve[i]&1) ve[i+1]+=ve[i]/2,ve[i]=ve[i]%2;
			else if(ve[i]) 
			
				int w=ve[i]/2-1;
				ve[i+1]+=w;
				ve[i]-=w*2;
			
		for(int i=0;i<ve.size();i++) cnt+=ve[i];
		cout<<cnt<<'\\n';
	
	return 0;

消灭星星【二进制枚举】

#include<bits/stdc++.h>
using namespace std;
const int N=25;
string s[N];
int t,n,m,k;
bool check(map<char,int>mp)

	map<int,int>x,y;
	mp['*']=1,mp['.']=1;
	for(int i=0;i<n;i++)
	
		bool flag=1;
		for(int j=0;j<n;j++) 
			if(mp.count(s[i][j])==0) flag=0;//该字母不可删除
		if(flag) x[i]=1;//说明这一行都是可删的
	
	for(int i=0;i<n;i++)
	
		bool flag=1;
		for(int j=0;j<n;j++) 
			if(mp.count(s[j][i])==0) flag=0;
		if(flag) y[i]=1;//说明这一列都是可删的
	
	int flag=1;
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			if(s[i][j]=='*')
			
				if(x[i]==0&&y[j]==0) flag=0;//说明该字母所属的行和列都不可删除
			
	return flag;

int main(void)

	cin>>t;
	while(t--)
	
		cin>>n>>m>>k;
		for(int i=0;i<n;i++) cin>>s[i];
		vector<char>ve;
		for(int i=0;i<m;i++) ve.push_back(char('A'+i));
		//撑死删k个字母 
		bool flag=0;
		for(int i=0;i<(1<<m);i++)
		
			map<char,int>mp;
			for(int j=0;j<m;j++)
				if(i>>j&1) mp[('A'+j)]++;
			if(mp.size()>k) continue;//最多删k个不同的字母
			if(check(mp)) flag=1;
		
		if(flag) puts("yes");
		else puts("no");
	
	return 0;

春游【贪心】


考虑,2人的便宜还是3人的便宜。尽可能用便宜的。
但是有一个坑点就是假如2人便宜,2人的组队后还有1个人该咋办。 是再拿一个2人船,还是拿一组2人的再加这1个用个三人船。
你会发现前面的整体很好分,但是最后的余数还得分开讨论。很麻烦。
故直接将总数减去一个值,将前面的按最优分组。剩下的余数直接暴力即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
int main(void)

	int t;cin>>t;
	while(t--)
	
		LL n,a,b; cin>>n>>a>>b;
		if(a/2.0<=b/3.0)
		
			LL cnt=max(0ll,(n-10)/2);//2人船的个数  n-10 是多拿些直接暴力的处理边界
			n=n-cnt*2;
			LL sum=cnt*a;
			LL temp=1e13;
			for(int i=0;i<=20;i++)
				for(int j=0;j<=20;j++)
					if((i*2+j*3)>=n) temp=min(temp,i*a+j*b);
			cout<<sum+temp<<'\\n';
		
		else
		
			LL cnt=max(0ll,(n-10)/3);//3人船的个数 
			n=n-cnt*3;
			LL sum=cnt*b;
			LL temp=1e13;
			for(int i=0;i<=30;i++)
				for(int j=0;j<=30;j++)
					if((i*2+j*3)>=n) temp=min(temp,i*a+j*b);
			cout<<sum+temp<<'\\n';
		
	
	return 0;

五连珠【模拟】

#include<bits/stdc++.h>
using namespace std;
int t,a[15][15],b[15][15],op[40];
int st1[15][15],st2[15][15];
map< int,pair<int,int> >mp1,mp2;
bool f1(int x,int y)

	st1[x][y]=1;
	int flag=0,cnt=0;
	
	for(int i=0;i<5;i++) if(st1[i][y]) cnt++;
	if(cnt==5) flag=1;
	
	cnt=0;
	for(int i=0;i<5;i++) if(st1[x][i]) cnt++;
	if(cnt==5) flag=1;
	
	cnt=0;
	for(int i=0,j=0;i<5&&j<5;i++,j++) if(st1[i][j]) cnt++;
	if(cnt==5) flag=1;
	
	cnt=0;
	for(int i=0,j=4;i<5&&j>=0;i++,j--) if(st1[i][j]) cnt++;
	if(cnt==5) flag=1;
	return flag;

bool f2(int x,int y)

	st2[x][y]=1;
	int flag=0,cnt=0;
	
	for(int i=0;i<5;i++) if(st2[i][y]) cnt++;
	if(cnt==5) flag=1;
	
	cnt=0;
	for(int i=0;i<5;i++) if(st2[x][i]) cnt++;
	if(cnt==5) flag=1;
	
	cnt=0;
	for(int i=0,j=0;i<5&&j<5;i++,j++) if(st2[i][j]) cnt++;
	if(cnt==5) flag=1;
	
	cnt=0;
	for(int i=0,j=4;i<5&&j>=0;i++,j--) if(st2[i][j]) cnt++;
	if(cnt==5) flag=1;
	return flag;

int main(void)

	cin>>t;
	while(t--) 
	
		for(int i=0;i<5;i++)
			for(int j=0;j<5;j++)
			
				cin>>a[i][j];
				mp1[a[i][j]]=i,j;
			
		for(int i=0;i<5;i++)
			for(int j=0;j<5;j++)
			
				cin>>b[i][j];
				mp2[b[i][j]]=i,j;
			
		memset(st1,0,sizeof st1);
		memset(st2,0,sizeof st2);
		for(int i=0;i<25;i++) cin>>op[i];
		bool flag1=0,flag2=0;
		for(int i=0;i<25;i++)
		
			int x1=mp1[op[i]].first,y1=mp1[op[i]].second;
            int x2=mp2[op[i]].first,y2=mp2[op[i]].second;
			if(f1(x1,y1)) flag1=1;
			if(f2(x2,y2)) flag2=1;
			if(flag1||flag2) break;
		
		if(flag1&&flag2) puts("0");
		else if(flag1) puts("1");
		else puts("2");
	
	return 0;

有始有终【双向广搜】

#include牛客白月赛8题解

牛客白月赛4 题解

牛客白月赛11题解

牛客白月赛12题解

牛客白月赛10题解

牛客白月赛14题解