CCPC-Wannafly & Comet OJ 夏季欢乐赛(2019)【6/9】

6/9

已过:A.B.C.G.H.I

还没过:D.E.F

题目列表

 

A.完全k叉树

B.距离产生美

C.烤面包片

G.篮球校赛

H.分配学号

I.Gree的心房


A.完全k叉树

算出层数,判断最后一层的树有没有超过k个

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

int main() {
	int t;
	for(cin>>t; t; t--) {
		ll n, k, cnt = 0, now = 1;
		cin>>k>>n;
		if(k == 1){
			cout<<(n-1)<<endl; 
		}else {
			while(n){
				n -= now;
				now *= k;
				cnt++;
				if(n < now){
					break;
				}
			}
			ll ans;
			if(n == 0) {
				ans = cnt*2-2;
			}else if(n <= now/k){
				ans = cnt*2-1;
			}else {
				ans = cnt*2;
			}
			cout<<ans<<endl;
		}
		
	}
}

B.距离产生美

贪心想,如果相邻两个数差值小于k,改掉后面这个数为 特别大的 数, 那么后面的差值肯定符合,可以跳过

/*
Algorithm:
Author: anthony1314
Creat Time:
Time Complexity:
*/

#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cstring>
#include<cstdio>
//#include<bits/stdc++.h>
#define ll long long
const int maxn = 100005;
const int mod = 1e9+7;
#define line printf("--------------");
using namespace std;
ll a[maxn];
int n, k;
int main() {
	cin>>n>>k;
	for(int i = 0; i < n; i++){
		scanf("%lld", &a[i]);
	} 
	int ans = 0;
	for(int i = 1; i < n; i++) {
		if(abs(a[i]-a[i-1]) < k){
			i++;
			ans++;
		}
	}
	cout<<ans<<endl;
	return 0;
}

C.烤面包片

1!!! = 1!! = 1! = 1

2!!! = 2!! = 2! =2

4!!! = 24!! > 1e9

我***了 这么简单都不知道

所以只有当n=3的情况需要去计算

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll c(ll n, ll p) {
	if(n == 0)return 0;
	ll ans = 1;
	for(int j = 2; j <= n; j++) {
		ans = ans * j % p;
	}
	return ans % p;
}

int main() {
	ll h,k;
	cin>>h>>k;
	if(h == 0) {
		cout<<1%k;
	} else if(h < 3) {
		cout<<h%k;
	} else if (h > 3){
		cout<<0;
	}else {
		ll q = c(h, k);
		q = c(q, k);
		q = c(q, k);
		cout<<q<<endl;
	}

	return 0;
}

G.篮球校赛

直接算出每项能力值前五的人为谁,用个数组存起来,进行dfs

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5+5;
bool vis[maxn];
ll co[maxn][6], ans;
int maxx[6][6];
int n;
void dfs(int now, ll tmp){
	if(now == 6){
		ans = max(ans, tmp);
		return;
	}
	for(int i = 1; i <= 5; i++){//循环第now种能力第i大的能力值 
		if(vis[maxx[now][i]]) continue; 
		vis[maxx[now][i]] = 1;
		dfs(now+1, tmp + co[maxx[now][i]][now]);
		vis[maxx[now][i]] = 0;
	}
}
int main() {
	scanf("%d", &n);
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= 5; j++){
			scanf("%lld", &co[i][j]);
			for(int k = 1; k <= 5; k++){
				if(co[i][j] > co[maxx[j][k]][j]){
					for(int h = 5; h >= k+1; h--){
						maxx[j][h] = maxx[j][h-1];
					}
					maxx[j][k] = i;
					break;
				}
			}
		}
	}
	dfs(1, 0);
	cout<<ans<<endl;
}

H.分配学号

排个序,对于每一个判断一下其需不需要进行加,需要加的方案数为其与应该增加到的数的差值+1,方案数相乘即可

/*
Algorithm:
Author: anthony1314
Creat Time:
Time Complexity:
*/

#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cstring>
#include<cstdio>
//#include<bits/stdc++.h>
#define ll long long
const int maxn = 100005;
const int mod = 1e9+7;
#define line printf("--------------");
using namespace std;
ll a[maxn];
int n;
int main() {
	cin>>n;
	for(int i = 0; i < n; i++){
		scanf("%lld", &a[i]);
	} 
	sort(a, a+n);
	ll ans = 1;
	
	for(int i = 0, j; i < n; i = j){
		for(j = i+1; j < n && a[j] < a[i] + j-i; j++){
			ans = ans * (a[i]+j-i -a[j]+1) % mod;//当前大小 与最大数的大小的差值就是可以变成的方案数 
//			cout<<ans<<endl;
		}
	}
	cout<<ans<<endl;
	return 0;
}

I.Gree的心房

判断一下方块的数量会不会多到挡到路即可,最优就是靠边的路

/*
Algorithm:
Author: anthony1314
Creat Time:
Time Complexity:
*/

#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cstring>
#include<cstdio>
//#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define mod 1e9 + 7
#define line printf("--------------");
using namespace std;

int main() {
	ll n, m, k;
	cin>>n>>m>>k;
	if(k > (n-1) * (m-1)){
		puts("-1");
	}else {
		cout<<n+m-2<<endl;
	}
	return 0;
}

 

全部评论

相关推荐

我也曾抱有希望:说的好直白
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务