牛客竞赛_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;
}