牛客小白月赛23

所有的伟大,都是从最初的平凡开始的。

题目链接点击就进去了

A

题意:一个图大小最大为(n行m列)20行100000列,带有*和.的图,每次可以消除a行b列,问采用最佳的消除方式能否把带星星的消除掉。

题解:dfs暴力,因为只有20行复杂度只是2^20,然后在乘以m,总的复杂度为2 ^ 20 * m,这么暴力竟然过了

思路:主要思路是dfs,深搜,如果深搜到最后一行的话直接return了,当回溯到最后一行且,消除的行数达到最大的时候的话,并且这种方式剩下待消灭的列可以被消灭则将标识位flag标记为true,这个是回溯的源头,也就是有解的标志,如果没达到最后一行的话,就一直,回溯下去,往下一行,继续深搜,如果好了的话就剪枝,如果没好的话就接着回溯,这次already+1,然后给当前行标记上。

代码:

#include<iostream>
using namespace std;
const int maxn=1e5+1;
int vis[maxn];
char g[21][maxn];
int n,m,a,b;
bool flag=false;
bool check()
{
	int res=0;
	for(int i=0;i<m;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(!vis[j] && g[j][i]=='*'){
				res++;
				break;
			}
		}
	}
	if(res>b) return false;
	else return true;
}
void dfs(int now,int already){
	if(now==n){
		if(already==a && check()){
			flag=true;
		}
		return;
	}
	vis[now]=0;
	dfs(now+1,already);
	if(flag) return ;
	if(already<a){
		vis[now]=1;
		dfs(now+1,already+1);
	}
}
int main()
{
	int t;
	cin>>t;
	while(t--){
		flag=false;
		cin>>n>>m>>a>>b;
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				cin>>g[i][j];
			}
		}
		dfs(0,0);
		if(flag) cout<<"yes"<<endl;
		else cout<<"no"<<endl;
	}
	return 0;
}

B

题意:输入p,找出最小的n,使得 n!% p == 0成立。
题解:怎么搞呢???涉及到知识盲区了……,emmmm,python?
对忘了我会python了。。。。。。
试一下吧!

t = int(input())
sum = 1
k = 0
while t:
    t-=1
    sum = 1
    p = int(input())
    for i in range(1,p+1):
        sum *= i
        if sum%p==0 :
            k=i
            break
    print(k)

这个题有点强把python给卡了,好像的确会卡掉。。。
TLE
那下面进入正解吧。
思路:类似与素数筛吧,先对p元素进行质因子分解,然后采取二分的方法,l=0,r=p,即可,然后mid,判断它的每个质因子个数,是否,比p的质因数个数多,如果多的话,说明mid偏大了,则右区间左移动,如果少的话,则左区间右移,二分用那个二进制移位比较好,可以防止l+r超出整型的范围。
代码:

#include<iostream>
#include<string.h>
using namespace std;
const int maxn=1e5+10;
int p,num[maxn],prime[maxn],k;
bool judge(int x)
{
	for(int i=1;i<=k;i++)
	{
		int n=x,num_prime=0;
		while(n){
			num_prime+=n/prime[i];
			n/=prime[i];
		}
		if(num_prime<num[i]) return false;
	}
	return true;
}
void solve()
{
	k=0;
	//分解P的质因数
	for(int i=2;i*i<=p;i++)
	{
		if(p%i==0)
		{
			prime[++k]=i;
			while(p%i==0){
				num[k]++;
				p/=i;
			}
		}
	}
	//这个是一个细节,如果p是质数的话,就直接把P仍进去就好了
	if(p>1) {
		prime[++k]=p;
		num[k]++;
	}
	int l=1,r=1e9,ans;
	//二分,judge函数,是判断mid的质因数个数,和p的质因数个数的比较
	//这样就可以有效的二分出来
	while(l<=r){
		int mid=(l+r)>>1;
		if(judge(mid)){
			r=mid-1;
			ans=mid;
		}else
			l=mid+1;
	}
	memset(num,0,sizeof(num));
	cout<<ans<<endl;
}
int main()
{
	int t;
	cin>>t;
	while(t--){
		cin>>p;
		solve();
	}
	return 0;
}

E

签到题吧……

题目链接自己理解E
永远都是2^32次方吧

python最短代码

print(4294967296)

I

题意:寻找最大连续子串,
比如acbcc 的最大自串是cc , abc的最大子串是c,helloworld的最大子串是world,然后按题意暴力就行

题解:暴力,找出最大字母,记录下位置来,然后判断每个最大子串的大小,大的后缀替换掉前面的就行了

代码:

#include<bits/stdc++.h>
#define sc(x) scanf("%lld",&x);
#define pf printf
#define rep(i,s,e) for(int i=s;i<=e;i++)
#define dep(i,e,s) for(int i=e;i>=s;i--)
using namespace std;
#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
string s;
int pos,cnt,r,l;
bool pd(int l,int r)
{
	string s1,s2;
	s1=s.substr(l,s.size()-l);
	s2=s.substr(r,s.size()-r);
	if(s1>s2) return true;
	else	return false;
}
int main()
{
	SIS;
	//加速cin/cout
	cin>>s;
	char c=s[0];
	for(int i=1;i<s.size();i++)
	{
		if(s[i]>c){
			pos=i;
			c=s[i];
		}
	}
	int tl,tr;
	l=pos;
	for(int i=pos+1;i<s.size();i++)
	{
		if(s[i]==c){
			r=i;
		if(!pd(l,r)) l=r;
		}
	}
	for(int i=l;i<s.size();i++)
		cout<<s[i];
	return 0;
}

J

题意:给一串数字,找出其中差值最大的数来,并输出最大差值
我是用set维护,取第一个和最后一个就行了,其实直接min,max统计也行,而且不占内存
代码:

#include<bits/stdc++.h>
#define sc(x) scanf("%lld",&x);
#define pf printf
#define rep(i,s,e) for(int i=s;i<=e;i++)
#define dep(i,e,s) for(int i=e;i>=s;i--)
using namespace std;
#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int main()
{
	SIS;
	//加速cin/cout
	int n;
	cin>>n;
	set<int> st;
	for(int i=1;i<=n;i++){
		int t;cin>>t;st.insert(t);
	}
	set<int> ::iterator it=st.begin(),ee=st.end();
	ee--;
	int k1=*it,k2=*ee;
	cout<<k2-k1<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值