2022-12-10 21:48阅读: 185评论: 0推荐: 0

2022年浙大城市学院新生程序设计竞赛(同步赛)

A. OP (Nowcoder48876 A)

题目大意

输出fengqibisheng, yingyueerlai!

解题思路

python最快

我错了,php直接打这个字符串就可以了

神奇的代码
print("fengqibisheng, yingyueerlai!")


B. Steel of Heart (Nowcoder48876 B)

题目大意

一个打怪模拟题

解题思路

按照题意模拟即可,用数组维护被动生效时间。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
template <typename T>
void read(T &x) {
int s = 0, c = getchar();
x = 0;
while (isspace(c)) c = getchar();
if (c == 45) s = 1, c = getchar();
while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
if (s) x = -x;
}
template <typename T, typename... rest>
void read(T &x, rest&... Rest) {
read(x);
read(Rest...);
}
template <typename T>
void write(T x, char c = ' ') {
int b[40], l = 0;
if (x < 0) putchar(45), x = -x;
while (x > 0) b[l++] = x % 10, x /= 10;
if (!l) putchar(48);
while (l) putchar(b[--l] | 48);
putchar(c);
}
int la[6];
int main(void) {
LL h1, h2;
int n;
read(h1, h2, n);
for(int i = 0; i < 6; ++ i)
la[i] = -2000;
bool own = false;
auto calc = [](LL x){
long long qwq = floor((125 + 1.0 * x * 0.06) * 0.1);
return qwq;
};
for(int i = 1; i <= n; ++ i){
int m, s, k;
scanf("%d:%d", &m, &s);
int t = m * 60 + s;
read(k);
if (k == 1){
h1 += 800;
own = true;
}else if (k == 2){
h1 += h2;
}else{
int target;
read(target);
if (own && t - la[target] >= 30){
h1 += calc(h1);
la[target] = t;
}
}
}
write(h1, '\n');
return 0;
}


C. Add 9 Zeros (Nowcoder48876 C)

题目大意

给定n个数字ai,问 ai+9不是这n个数的个数。

解题思路

mapset记录下出现的数即可。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main(void) {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
set<int> qwq;
int n;
cin >> n;
for(int i = 1; i <= n; ++ i){
int x;
cin >> x;
qwq.insert(x);
}
set<int> qaq;
for(auto i : qwq){
if (qwq.find(i + 9) == qwq.end())
qaq.insert(i + 9);
}
cout << qaq.size() << '\n';
return 0;
}


D. Cutting with Lines Ⅰ (Nowcoder48876 D)

题目大意

<++>

解题思路

<++>

神奇的代码


E. Cutting with Lines Ⅱ (Nowcoder48876 E)

题目大意

<++>

解题思路

<++>

神奇的代码


F. Survivor (Nowcoder48876 F)

题目大意

n名玩家,第 i名玩家初始 ai血,每分钟扣 bi血,对其实施回复魔法,一次回复 ci血。

现你可以实施不超过k次恢复魔法,问 m分钟后存活玩家的最大数量。玩家血量小于等于0即死亡。

解题思路

预处理让第i名玩家在 m分钟后存活的最少实施回复魔法次数数组 cnti,从小到大依次恢复直到超过 k

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main(void) {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int n;
LL m, k;
cin >> n >> m >> k;
vector<LL> a(n), b(n), c(n), cnt(n);
for(auto &i : a)
cin >> i;
for(auto &i : b)
cin >> i;
for(auto &i : c)
cin >> i;
for(int i = 0; i < n; ++ i){
a[i] -= m * b[i];
if (a[i] <= 0){
cnt[i] = (-a[i] + 1 + c[i] - 1) / c[i];
}else {
cnt[i] = 0;
}
}
sort(cnt.begin(), cnt.end());
int ans = 0;
while(ans < n){
if (k - cnt[ans] >= 0){
k -= cnt[ans];
++ ans;
}else
break;
}
cout << ans << endl;
return 0;
}


G. Red Black Tree (Nowcoder48876 G)

题目大意

给定一个直角等腰三角形摆放的格子,初始状态下一些格子颜色为黑色。其余为红色。现在要求将最小数量的红色格子变成黑色,满足以下两个要求:

  • 黑色格子(i,j)的下面两个格子 (i+1,j),(i+1,j+1) 颜色也必须是黑色
  • 两个相邻黑色格子(i,j),(i,j+1)的上一个格子(i1,j)颜色也必须是黑色

问黑色格子数量的最小值。

解题思路

不考虑第二个条件的话,同一列考虑最上面(行号最小)的黑色格子,最终局面就是一些黑色直角等腰三角形的叠加。

加上第二个条件的话,造成的额外影响就是,两个相互覆盖的黑色直角三角形会融合,变成一个更大的直角等腰三角形。

模拟该过程统计答案即可。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const int N = 1e6 + 8;
int maxx[N];
int yy[N], cnt;
LL calc(int n){
return 1ll * n * (n + 1) / 2;
}
int main(void) {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int n, k;
cin >> n >> k;
for(int i = 1; i <= k; ++ i){
int x, y;
cin >> x >> y;
++ cnt;
yy[cnt] = y;
maxx[y] = max(maxx[y], n - x + y + 1);
}
sort(yy + 1, yy + 1 + cnt);
cnt = unique(yy + 1, yy + 1 + cnt) - yy - 1;
int l = yy[1];
int r = maxx[yy[1]];
LL ans = 0;
for(int i = 2; i <= cnt; ++ i){
if (r >= yy[i]){
r = max(r, maxx[yy[i]]);
}else{
ans += calc(r - l);
l = yy[i];
r = maxx[yy[i]];
}
}
ans += calc(r - l);
cout << ans << '\n';
return 0;
}


H. Beautiful String (Nowcoder48876 H)

题目大意

给定一个字符串s,求满足以下任意条件之一的长度为 n的各位互不相同的字符串 t的数量

  • t从左到右的字母的字典序依次增大,且 t1(第一个字母)在 s出现过
  • t中的字母在串 s都出现过。

注意串 s和串 t都由英文前18位小写字母组成。

解题思路

考虑满足第一个条件的字符串个数。

枚举第一个字母,其在s出现过,假设是第i个英文字母,则剩下位数的方案数就是 (18in1)

考虑满足第二个条件的字母串个数,假设s串出现了 m种字母,个数就是(mn)×n!(阶乘就是排列数) 。

再减去同时满足一二条件的个数,其实就是(mn)

因此答案就是is(18in1)+(mn)×(n!1)

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
#define FOR(i, x, y) for (decay<decltype(y)>::type i = (x), _##i = (y); i < _##i; ++i)
#define FORD(i, x, y) for (decay<decltype(x)>::type i = (x), _##i = (y); i > _##i; --i)
const int N = 18;
int cnt[N], n, m;
LL jie[20];
LL C(int n, int m){
if (n < m || n < 0 || m < 0)
return 0;
return jie[n] / jie[m] / jie[n - m];
}
LL A(int n, int m){
if (n < m || n < 0 || m < 0)
return 0;
return jie[n] / jie[n - m];
}
int main(void) {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
jie[0] = 1;
FOR(i, 1, N + 1)
jie[i] = jie[i - 1] * i;
int t;
cin >> t;
while(t--){
string s;
cin >> s >> n;
for(auto &i : s)
cnt[i - 'a'] ++;
LL tmp = 0;
int cc = 0;
for(int i = 0; i < N; ++ i)
if (cnt[i] != 0){
m |= (1 << i);
++ cc;
tmp += C(18 - i - 1, n - 1);
}
tmp -= C(cc, n);
tmp += A(cc, n);
cout << tmp << '\n';
for(int i = 0; i < N; ++ i)
cnt[i] = 0;
}
return 0;
}


I. Digit Problem (Nowcoder48876 I)

题目大意

已知数x,y在二进制下有 a1b0,其差 z=xyc1

给一个可能的 x,y。不存在输出 1

解题思路

构造题从简单入手。

考虑xy的所有 1都在高位,此时其z没有 1

考虑 y的最低位的 1往低位移1位,则 z会多一个 1

此时 bc的时候可采用该方法构造。

考虑 b<c

假设 zc1都在低位,令y=xz,可以看成 y=x(z+1)+1 ,相当于把x的高c+1位的 1放到最低位,1的个数和 x一样。

注意a=0,b=0,a+b<=c的特殊情况。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main(void) {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int a, b, c;
cin >> a >> b >> c;
if (a + b <= c || (a == 0 && c != 0) || (b == 0 && c != 0))
cout << -1 << '\n';
else{
if (b >= c){
string x(a + b, '0'), y(a + b, '0');
fill(x.begin(), x.begin() + a, '1');
if (a > 0){
fill(y.begin(), y.begin() + a - 1, '1');
y[a + c - 1] = '1';
}
cout << x << '\n';
cout << y << '\n';
}else{
string x(a + b, '0'), y(a + b, '0');
fill(x.begin(), x.begin() + a, '1');
fill(y.begin(), y.begin() + a, '1');
y[a + b - c - 1] = '0';
y.back() = '1';
cout << x << '\n';
cout << y << '\n';
}
}
return 0;
}


J. Simple Game (Nowcoder48876 J)

题目大意

n个数字,每人每回合拿走一个数字,直至无数字剩下。Alice先手, Bob后手。最后若两人拿走数的和的差是奇数, AliceA胜,否则 Bob胜。问两者绝顶聪明的情况下谁胜。

解题思路

奇偶性的相加减,也就是模2的加减其实等效于异或,即这两个操作是一样的。

因此无论他们怎么拿,最终情况都是一样,即和是奇数就Alice胜,否则 Bob胜。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main(void) {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int n;
cin >> n;
int ans = 0;
while(n--){
int x;
cin >> x;
ans ^= (x & 1);
}
if (ans)
cout << "Alice" << '\n';
else
cout << "Bob" << '\n';
return 0;
}


K. Bit (Nowcoder48876 K)

题目大意

假设当前数为x,给定n个操作,操作有三种类型:

  • 给定 a,令x=x&a,即与运算。
  • 给定 a,令x=x|a,即或运算。
  • 给定 a,令x=xa,即异或运算。

q个询问,每个询问给定一个 r,要求从 [0,r]中选定 一个数x,使得该数经过这 n个操作后的数最大。

解题思路

注意到位运算,二进制位之间独立,因此依次考虑每个数位取值01

预处理数组f[i][j]表示第 i 位取值为j01), 经过这n次操作后变成的值。

然后就从高位开始依次考虑每位取值为 01。取值过程考虑是否有最高位限制(不大过 r),就像数位 dp里的limit变量。

即当前位如果可取0,1,且最终值,取 1的时候更大,那肯定取 1,否则就取 0

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const int N = 1e5 + 8;
int n, q;
int f[35][2];
int op[N], num[N];
int cal(int type, int lv, int rv){
if (type == 1)
return lv & rv;
else if (type == 2)
return lv | rv;
else
return lv ^ rv;
}
int calc(int pos, int x){
for(int i = 1; i <= n; ++ i){
x = cal(op[i], ((num[i] >> pos) & 1), x);
}
return x;
}
int b[32], pos, ans[32];
void dfs(int pos, int limit){
if (pos < 0)
return;
if (limit && b[pos] == 0){
ans[pos] = 0;
dfs(pos - 1, limit && (b[pos] == 0));
}
else{
int g1 = f[pos][1];
int g0 = f[pos][0];
if (g1 > g0){
ans[pos] = 1;
dfs(pos - 1, limit && (b[pos] == 1));
}else{
ans[pos] = 0;
dfs(pos - 1, limit && (b[pos] == 0));
}
}
}
void solve(int r){
pos = -1;
while(r){
++ pos;
b[pos] = (r & 1);
r >>= 1;
}
dfs(pos, 1);
}
int main(void) {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> q;
for(int i = 1; i <= n; ++ i){
cin >> op[i] >> num[i];
}
for(int i = 0; i < 30; ++ i){
f[i][0] = calc(i, 0);
f[i][1] = calc(i, 1);
}
while(q--){
int r;
cin >> r;
solve(r);
int val = 0;
for(int i = 0; i <= pos; ++ i){
if (ans[i])
val |= (1 << i);
}
cout << val << '\n';
}
return 0;
}


L. Elden Ring (Nowcoder48876 L)

题目大意

2n个人, 各n个人围城一个环共两个环。从1n+1人从 1报数,报到m的倍数的两人交换位置。问报到k时的局面。

解题思路

k不大,按题意模拟即可。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main(void) {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int n;
cin >> n;
vector<int> a(n), b(n);
iota(a.begin(), a.end(), 1);
iota(b.begin(), b.end(), n + 1);
int m, k;
cin >> m >> k;
int pos = 0;
int cnt = m;
for(int i = 1; i <= k; ++ i){
-- cnt;
if (cnt == 0){
swap(a[pos], b[pos]);
cnt = m;
}
++ pos;
if (pos == n)
pos = 0;
}
for(int i = 0; i < n; ++ i)
cout << a[i] << ' ';
for(int i = 0; i < n; ++ i)
cout << b[i] << ' ';
return 0;
}


本文作者:~Lanly~

本文链接:https://www.cnblogs.com/Lanly/p/16972427.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   ~Lanly~  阅读(185)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.