牛客周赛 Round 24

发布时间:2023年12月20日

题目链接:

牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ (nowcoder.com)

小红的矩阵构造

题目大致意思是: 小红想让你构造一个 ?n行 ?n列的矩阵,矩阵中的元素为1到?n * n? 每个数只出现1次。小红希望每两个相邻的数之均为奇数

分析:

先把第一层按照1到n的顺序给排了, 第一层一定是满足条件的,因为每两个相邻的数都是奇偶性不一样的。?从第二层开始,看看这个数的上一层是奇数还是偶数,我上面的是奇数,那我就偶数这样相加就是奇数了,反之

代码:

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

int a[110][110];

signed main() {
	
	int n;
	cin >> n;
	for(int i = 1; i <= n; ++ i )a[1][i] = i;
	int ji = 0, ou = 0;
	
	if(n % 2) {
		ji = n + 2;
		ou = n + 1;
	} else {
		ji = n + 1;
		ou = n + 2;
	}

	for(int i = 2; i <= n; ++ i ) {
		for(int j = 1; j <= n; ++ j ) {
			if(a[i - 1][j] % 2 == 0) {
				a[i][j] = ji;
				ji += 2;
			} else {
				a[i][j] = ou;
				ou += 2;
			}
		}
	}
	
	for(int i = 1; i <= n; ++ i ) {
		for(int j = 1; j <= n; ++ j ) {
			cout << a[i][j] << ' ';
		}
		cout << endl;
	}
	return 0;
}

小红的因子?

小红拿到了一个正整数n,她希望找到n的一个最小因子p,满足p * p > n。你能帮帮她吗?一共有t组询问。

分析:

i从2到sqrt(n)循环? 枚举的是每个数的因子,如果这个i是n的因子的话,那么n/i也是n的因子

代码:

#include<bits/stdc++.h>
#define int long long

using namespace std;

int t, x, ret;

signed main() {
	
	cin >> t;

	while(t--) {
	   
		cin >> x; 
		ret = x;
		bool flag = false;
		for(int i = 2; i <= x / i; ++ i ) {
			if(x % i == 0) {
				if(i * i > x) {
					flag = true;
					ret = min(ret, i);
				}
				int p = x / i;
				if(p * p > x) {
					flag = true;
					ret = min(ret, p);
				}
			}
		}
		if(flag == false) {
			ret = x;//质数 
		}
		cout << ret << endl;
	}
	return 0;
}

小红的小数点串?

题目描述

小红拿到了一个仅包含数字和小数点('.')的字符串。她准备把这个字符串切分,使得切分后的每个数(整数或小数)都合法。小红想知道,切分后所有数之和的最大值是多少。
我们定义,合法的小数为:只包含一个小数点,且小数点的左和右均为数字字符。例如"0.23"、"125.24"、"7.0"为合法小数,而".45"、"345."为不合法小数。

分析:

贪心的策略,要是小数点的话 我只要小数点后面一位就行了,剩下的让他们 变成整数 对我的和更有利,比如123.456 这个就拆成 123.4 + 56

代码:

#include<bits/stdc++.h>
#define int long long

using namespace std;

string s;

signed main() {
	cin >> s;
	int n = s.size();
	double ret = 0;
	
	double zs = 0;//整数 
	double xs = 0;//小数 
	
	for(int i = 0; i < n; ++ i ) {
		if(s[i] != '.')
		zs = zs * 10 + (s[i] - '0');
		if(s[i - 1] == '.') {
			int x = s[i] - '0';
			zs -= x;
			zs /= 10;
			xs = 0.1 * x;
			ret += zs + xs;
			zs = 0;
			x = 0;
		}
	}
	printf("%.1f\n", (ret + zs));
	return 0;
}

小红的数组操作?

题目描述

小红拿到了一个数组,她每次可以进行如下操作:
选择一个数,使其减去 x。
小红希望 k 次操作之后,该数组的最大值尽可能小。请你求出这个尽可能小的最大值

输入描述:

第一行输入三个正整数 n、k 和 x,代表数组长度、操作次数以及每次操作减的数。
第二行输入 n 个正整数 a[i]?,代表小红拿到的数组。
1 <= n <= 1e5 1 <= a[i], k, x <= 1e9

输出描述:

一个整数,代表 k 次操作后,数组尽可能小的最大值。

分析:

问题的描述,就是典型的二分算法 ,注意l和r的边界取值,去极限的情况 数组里面值只有一个,且值是1,让你操作1e9次,每次减去1e9,那么最后的答案就是 1e9 * 1e9 - 1, 同理极限的情况下求去边界r

代码:

#include<bits/stdc++.h>
#define int long long

using namespace std;

const int N = 1e5 + 10;
int a[N];
 
int n, k, x;// k表示的是操作的次数 x表示的是每次减去的值 

bool check(int t) {
	int cs = 0;
	for(int i = 1; i <= n; ++ i ) {
		if(a[i] > t) {
			cs += (a[i] - t + x - 1) / x;
			if(cs > k)return true;
		} else {
			return false;
		}
	}
	return false;
}

bool cmp(int l, int r) {
	return l > r;
}

signed main() {
	cin >> n >> k >> x;
	for(int i = 1; i <= n; ++ i )cin >> a[i];
	sort(a + 1, a + n + 1, cmp);
	
	//二分?
	int l = -1e18, r = 1e20;
	while(l + 1 < r)  {
		int mid = l + r >> 1;
		if(check(mid))l = mid;
		else r = mid;
	}
	cout << l + 1 << endl;
	return 0;
}

文章来源:https://blog.csdn.net/m0_74304371/article/details/135099065
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。