牛客月赛42

Posted MangataTS

tags:

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

A.冰狱寒岚

思路

我们将这个数对2048取模得k,如果k大于等于1024那么我们就返回k-2048否则直接返回k

Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000009
ll ksm(ll a,ll b) 
	ll ans = 1;
	for(;b;b>>=1LL) 
		if(b & 1) ans = ans * a % mod;
		a = a * a % mod;
	
	return ans;


ll lowbit(ll x)return -x & x;

const int N = 2e6+10;

int a[N];
ll n,x;

ll f(ll k) 
	k %= 2048;
	if(k >= 1024) return (k-2048);
	else return k;


int main()

	cin>>n;
	for(int i = 1;i <= n; ++i) 
		cin>>a[i];
		a[i] = f(a[i]);
	
	for(int i = 1;i <= n; ++i) 
		cout<<a[i]<<" ";
	
	cout<<"\\n";
	
	
	return 0;

B.光之屏障

思路

我们用位运算模拟从小到大,或者从大到小模拟一下,看看是否有数落在这个范围内,如果有输出该数,否则输出-1

Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000009
ll ksm(ll a,ll b) 
	ll ans = 1;
	for(;b;b>>=1LL) 
		if(b & 1) ans = ans * a % mod;
		a = a * a % mod;
	
	return ans;


ll lowbit(ll x)return -x & x;

const int N = 2e6+10;

int a[N];
ll x,y;

int main()

	//ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--) 
		cin>>x>>y;
		bool fg = true;
		for(ll i = 0LL;i <= 32LL; ++i) 
			ll k = (1LL << i);
			if(k >= x && k <= y) 
				fg = false;
				cout<<k<<"\\n";
				break;
			
		
		if(fg) puts("-1");
	
	
	
	return 0;

C.寒潭烟光

思路

很显然算出 a n s = n × F ( x ) + n × x 0 + x 0 n + 1 ans=\\fracn \\times F(x) + n\\times x_0 + x_0n+1 ans=n+1n×F(x)+n×x0+x0,注意这里爆int,所以我们直接输出即可

Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000009
ll ksm(ll a,ll b) 
	ll ans = 1;
	for(;b;b>>=1LL) 
		if(b & 1) ans = ans * a % mod;
		a = a * a % mod;
	
	return ans;


ll lowbit(ll x)return -x & x;

const int N = 2e6+10;

int a[N];
ll n,f,x;

int main()

	int t;
	cin>>t;
	while(t--) 
		cin>>n>>f>>x;
		cout<<(n * f + n * x + x)/(n + 1LL)<<endl;
	
	return 0;

D.金蛇狂舞

思路

因为实际上只有三种走法:

  • 阶乘
  • 开根号然后向上取整
  • 开根号然后向下取整

所以直接搜索然后注意下数据范围剪枝即可:七步以上直接不搜,数据太大也不搜

Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000009
ll ksm(ll a,ll b) 
	ll ans = 1;
	for(;b;b>>=1LL) 
		if(b & 1) ans = ans * a % mod;
		a = a * a % mod;
	
	return ans;


ll lowbit(ll x)return -x & x;

const int N = 2e6+10;
ll x,y;
bool fg = false;
int ans = 0x3f3f3f3f;
ll f(ll k) 
	ll ans = 1;
	while(k) 
		ans *= k;
		k--;
	
	return ans;

map<ll,bool>vis;
void dfs(int cnt,ll loc) 
	if(cnt > 7 || loc > 10000000000LL ) 
		return;
	
	if(loc == y) 
		fg = true;
		ans = min(ans,cnt);
		return;
	
	if(loc <= 15)
	dfs(cnt+1,f(loc));//阶乘
	dfs(cnt+1,ceil(sqrt(loc * 1.0) * 1.0));//向上取整
	dfs(cnt+1,sqrt(loc*1.0));//向下取整


int main()

	int t;
	cin>>x>>y;
	dfs(0,x);
	if(fg) cout<<ans<<endl;
	else puts("-1");
	return 0;

E.暗灭侵蚀

思路

贪心的想,我们每次都跳动最左边的球以最右边的球为中心点,然后我们就能得到最优解,你可以这样想,我们每次移动都是最优的,这其实有点像斐波那契数列

Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000009
ll ksm(ll a,ll b) 
	ll ans = 1;
	for(;b;b>>=1LL) 
		if(b & 1) ans = ans * a % mod;
		a = a * a % mod;
	
	return ans;


ll lowbit(ll x)return -x & x;

// const int N = 2e6+10;
ll a,b,c,N;

int main()

	int t;
	cin>>t;
	while(t--) 
		cin>>a>>b>>c>>N;
		int cnt = 0;
		while(a < N && b < N && c < N) 
			ll ta = a;
			ll tb = b;
			ll tc = c;
			c = 2 * c - ta;
			a = tb;
			b = tc;
			cnt++;
		
		cout<<cnt<<"\\n";
	
	
	
	return 0;

F.火凤燎原

思路

可能很多同学想到了将度大于等于3的点都跑一次DFS,但是只能过部分数据

很明显有贡献的点的度一定是大于等于三的:

  • 此时这个 v 对于点 u 的贡献,是以 v 为根的子树大小减一(链的长度不少于 2,所以 v自己作为链的情况需要去除)。

我们稍加思索会发现一个结论,M为大于等于3的点的总数: a n s = ∑ i M n − d u i − 1 ans = \\sum_i^Mn-du_i-1 ans=iMndui1

证明后面补

Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000009
ll ksm(ll a,ll b) 
	ll ans = 1;
	for(;b;b>>=1LL) 
		if(b & 1) ans = ans * a % mod;
		a = a * a % mod;
	
	return ans;


ll lowbit(ll x)return -x & x;

const int N = 5e5+10;

vector<int> Edge[N];

int a[N];
ll n,x;
int t;

ll cnt;
bool vis[N];

void dfs(int loc,int deep) 
	if(vis[loc]) return;
	vis[loc] = true;
	if(deep >= 2) cnt++;
	for(int i = 0,len = Edge[loc].size();i < len; ++i) 
		dfs(Edge[loc][i],deep+1);
	


int main()

	scanf("%d",&t);
	while(t--) 
		scanf("%d",&n);
		for(int i = 1;i <= n; ++i) 
			Edge[i].clear();
		
		int u,v;
		for(int i = 1;i < n; ++i) 
			scanf("%d%d",&u,&v);
			Edge[u].push_back(v);
			Edge[v].push_back(u);
		
		ll ans = 0;
		for(int i = 1;i <= n; ++i) 
			if(Edge[i].size() >=3) 
                ans +=n - Edge[i].size() - 1;
		
		printf("%lld\\n",ans);
	
	
	
	return 0;

以上是关于牛客月赛42的主要内容,如果未能解决你的问题,请参考以下文章

牛客月赛43

博客总结第十周+牛客月赛

牛客月赛46部分题解

8/12 最小表示法+牛客月赛

牛客月赛:走出迷宫(Java)

牛客月赛60 F.被抓住的小竹(数学&推式子)