2022牛客寒假算法基础集训营2
A - 小沙的炉石
题目描述

输入描述

输出描述

样例输入
2 1
3
1
4
6
样例输出
YES
YES
NO
样例说明

思路
按道理来说, 所有斩杀线以下的都应该可以, 但是出现了两个特例绝对不是打表出来的
- m == 1, 此时无法凑出3
- m == 2, 此时无法凑出8
最大斩杀线, 先把所有的法术回复牌用完, 然后尽可能用出
代码
#include <iostream>
using namespace std;
typedef long long LL;
LL n, m;
int main() {
cin >> n >> m;
LL t = min(n, m + 1);
LL maxv = (m + 1) * t + t * (t - 1) / 2;
int T;
cin >> T;
while (T -- ) {
LL x;
cin >> x;
if (m == 1 && x == 3) puts("NO");
else if (m == 2 && x == 8) puts("NO");
else if (x <= maxv) puts("YES");
else puts("NO");
}
}
C - 小沙的杀球
题目描述

输入描述

输出描述

样例输入
10 2 1
111111
样例输出
5
样例说明

思路
总体来说就是贪心, 能杀就杀, 不能杀就回血
如果后面存在一次高球, 可以在本次杀球休息一次完成击杀, 那么在本次杀球是一样的结果
代码
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int main() {
long long n, a, b;
cin >> n >> a >> b;
string str;
cin >> str;
int ans = 0;
for (auto i : str) {
if (n >= a && i == '1') ans ++, n -= a;
else n += b;
}
cout << ans << endl;
return 0;
}
E - 小沙的长路
题目描述

输入描述

输出描述

样例输入
3
样例输出
2 3
样例说明

思路
根据规律我们发现最短路就是n - 1(汉密尔顿路径), 而最长路就是(欧拉回路)
注意欧拉回路的前提条件
代码
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
cout << n - 1 << ' ' << (n % 2 == 0 ? n * (n - 1ll) / 2 - (n / 2 - 1) : n * (n - 1ll) / 2) << endl;
return 0;
}
F - 小沙的算数
题目描述

输入描述

输出描述

样例输入
5 3
++*+
1 1 3 1 1
4 2
1 7
5 6
样例输出
9
15
20
思路
对于加法, 不管怎么修改都只是修改一个值, 我们每次删去原来的, 再加上新值就好
对于乘法, 所有乘号两边的数都被合并为一个整体, 利用并查集使其合并为一个点, 然后每次修改这个点即可, 结果仍是删去原来加上现在
代码
#include <iostream>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10, mod = 1e9 + 7;
int n, q;
string str;
LL a[N], b[N];
int st[N];
int p[N];
LL ans;
int find(int x) {
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
LL qmi(LL a, LL b) {
LL ans = 1;
while (b) {
if (b & 1) ans = (ans * a) % mod;
b >>= 1;
a = (a * a) % mod;
}
return ans;
}
int main() {
cin >> n >> q;
cin >> str;
for (int i = 1; i <= n; i ++) {
p[i] = i;
b[i] = 1;
cin >> a[i];
if (a[i] == 0) st[i] ++;
}
//p[1] = 1;
for (int i = 1; i < n; i ++ ) {
if (str[i - 1] == '*') p[i + 1] = p[i];
}
for (int i = 1; i <= n; i ++ ) {
b[p[i]] = (a[i] * b[p[i]]) % mod;
}
for (int i = 1; i <= n; i ++ )
if (p[i] == i) ans = (ans + b[i]) % mod;
//cout <<ans << endl;
while (q --) {
int x, y;
cin >> x >> y;
int t = find(x);
ans = (ans - b[t] + mod) % mod;
b[t] = (b[t] * qmi(a[x], mod - 2)) % mod;
a[x] = y;
b[t] = (b[t] * a[x]) % mod;
ans = (ans + b[t]) % mod;
cout << ans << endl;
}
return 0;
}
H - 小沙的数数
题目描述
输入描述

输出描述

样例输入
3 1
样例输出
3
样例说明

思路
异或值最大, 必然是每个二进制位置上有尽可能多的奇数个1, 而另一个条件数组和为m, 也就是说我们要将m中所有的二进制的1进行拆分, 分配到数组的n个位置上
代码
#include <iostream>
using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;
LL qmi(LL a, LL b) {
LL ans = 1;
while (b) {
if (b & 1) ans = (ans * a) % mod;
b >>= 1;
a = (a * a) %mod;
}
return ans;
}
LL calc(LL n) {
LL cnt = 0;
while (n) {
if (n & 1) cnt ++;
n >>= 1;
}
return cnt;
}
int main() {
LL n, m;
cin >> n >> m;
LL cnt = calc(m);
cout << qmi(n % mod, cnt) << endl; // 对于这里对n取模很迷惑
return 0;
}
I - 小沙的构造
题目描述

对称字符: "!'*+-.08:=^_WTYUIOAHXVM|
非对称字符: </[{(>\]})
输入描述

输出描述

样例输入1
3 1
样例输出1
OOO
样例输入2
3 3
样例输出2
<=>
思路
对称字串而已, 不满足的条件是, 即使全部使用非对称字符, 仍不满足m个异同字符
虚假的代码
#include <iostream>
#include <cstdio>
#include <string>
#define N 11000
using namespace std;
int n , m;
char a[N];
int main(){
cin >> n >> m;
if(m == 36){
cout << -1 << endl;
return 0;
}
string s = "\"!'*+-.08:=^_WTYUIOAHXVM|";
string s2 = "<\\[{(";
string s3 = ">/]})";
s = ' ' + s , s2 = ' ' + s2 , s3 = ' ' + s3;
int get = 0 , t = 1 , t2 = 1;
for (int i = 1;i <= n / 2;++ i){
if(get < m) {
if(m - get > 1 && t2 <= 5) a[i] = s2[t2] , a[n - i + 1] = s3[t2] , t2 ++ , get += 2;
else a[i] = s[t] , a[n - i + 1] = s[t] , get ++ , t ++;
}else{
a[i] = a[i - 1] , a[n - i + 1] = a[n - i + 2];
}
}
if(n % 2 == 1){
if(m - get == 1) a[n / 2 + 1] = s[t] , get ++;
else if(m == get) a[n / 2 + 1] = '"';
}
if(get < m) cout << -1 << endl;
else
for (int i = 1;i <= n;++ i) cout << a[i];
return 0;
}
真实的代码1(请各位欣赏暴力的美学)
#include <bits/stdc++.h>
using namespace std;
#define LL long long
// char s[40] = "<>\\/[]{}()\"!'*+-.08:=^_WTYUIOAHXVM|";
string s[36] = {
"",
"W",
"<>",
"<W>",
"<[]>",
"<[W]>",
"<[\\/]>",
"<[\\W/]>",
"<[\\{}/]>",
"<[\\{W}/]>",
"<[\\{()}/]>",
"<[\\{(W)}/]>",
"<[\\{(\"W\")}/]>",
"<[\\{(\"!W!\")}/]>",
"<[\\{(\"!'W'!\")}/]>",
"<[\\{(\"!'*W*'!\")}/]>",
"<[\\{(\"!'*+W+*'!\")}/]>",
"<[\\{(\"!'*+-W-+*'!\")}/]>",
"<[\\{(\"!'*+-.W.-+*'!\")}/]>",
"<[\\{(\"!'*+-.0W0.-+*'!\")}/]>",
"<[\\{(\"!'*+-.08W80.-+*'!\")}/]>",
"<[\\{(\"!'*+-.08:W:80.-+*'!\")}/]>",
"<[\\{(\"!'*+-.08:=W=:80.-+*'!\")}/]>",
"<[\\{(\"!'*+-.08:=^W^=:80.-+*'!\")}/]>",
"<[\\{(\"!'*+-.08:=^_W_^=:80.-+*'!\")}/]>",
"<[\\{(\"!'*+-.08:=^_TWT_^=:80.-+*'!\")}/]>",
"<[\\{(\"!'*+-.08:=^_TYWYT_^=:80.-+*'!\")}/]>",
"<[\\{(\"!'*+-.08:=^_TYUWUYT_^=:80.-+*'!\")}/]>",
"<[\\{(\"!'*+-.08:=^_TYUIWIUYT_^=:80.-+*'!\")}/]>",
"<[\\{(\"!'*+-.08:=^_TYUIOWOIUYT_^=:80.-+*'!\")}/]>",
"<[\\{(\"!'*+-.08:=^_TYUIOAWAOIUYT_^=:80.-+*'!\")}/]>",
"<[\\{(\"!'*+-.08:=^_TYUIOAHWHAOIUYT_^=:80.-+*'!\")}/]>",
"<[\\{(\"!'*+-.08:=^_TYUIOAHXWXHAOIUYT_^=:80.-+*'!\")}/]>",
"<[\\{(\"!'*+-.08:=^_TYUIOAHXVWVXHAOIUYT_^=:80.-+*'!\")}/]>",
"<[\\{(\"!'*+-.08:=^_TYUIOAHXVMWMVXHAOIUYT_^=:80.-+*'!\")}/]>",
"<[\\{(\"!'*+-.08:=^_TYUIOAHXVM|W|MVXHAOIUYT_^=:80.-+*'!\")}/]>",
};
char t[10010];
int n, m;
int main() {
cin >> n >> m;
if (m == 1) {
for (int i = 1;i <= n;++i)
cout << "W";
cout << endl;
return 0;
}
if (m == 36) { cout << -1 << endl; return 0; }
if (n < s[m].size()) { cout << -1 << endl; return 0; }
if ((n - s[m].size()) % 2 == 0) {
int num = (n - s[m].size()) / 2;
for (int i = 1;i <= num;++i) cout << s[m][0];
cout << s[m];
for (int i = 1;i <= num;++i) cout << s[m].back();
cout << endl;
}
else {
int num = n - s[m].size();
if (s[m][s[m].size() / 2] != 'W') { cout << -1 << endl; return 0; }
for (int i = 1;i <= num / 2;++i) cout << s[m][0];
for (int i = 0;i <= s[m].size() / 2;++i) cout << s[m][i];
cout << s[m][s[m].size() / 2];
for (int i = s[m].size() / 2 + 1;i < s[m].size();++i) cout << s[m][i];
for (int i = 1;i <= num / 2;++i) cout << s[m].back();
cout << endl;
}
return 0;
}
真实的代码2
还没找到

K - 小沙的步伐
题目描述

输入描述

输出描述

样例输入
19283746
样例输出
1 1 1 1 8 1 1 1 1
思路
在5击球的话, 不计入5的数量
不在5击球的话, 计入本来的数量和5的数量
代码
#include <iostream>
using namespace std;
int cnt[20];
int main() {
string str;
cin >> str;
for (auto i : str)
cnt[i - '1'] ++;
for (int i = 0; i < 9; i ++)
if (i != 4) cout << cnt[i] << ' ';
else cout << (str.length() - cnt[i]) << ' ';
return 0;
}
L&&M - 小沙而remake
题目描述

题目给的C++代码
#include<bits/stdc++.h>
namespace GenHelper
{
int z1,z2,z3,z4,z5,u,res;
int get()
{
z5=((z1<<6)^z1)>>13;
z1=((int)(z1&4294967)<<18)^z5;
z5=((z2<<2)^z2)>>27;
z2=((z2&4294968)<<2)^z5;
z5=((z3<<13)^z3)>>21;
z3=((z3&4294967)<<7)^z5;
z5=((z4<<3)^z4)>>12;
z4=((z4&4294967)<<13)^z5;
return (z1^z2^z3^z4);
}
int read(int m) {
u=get();
u>>=1;
if(m==0)res=u;
else res=(u/2345+1000054321)%m;
return res;
}
void srand(int x)
{
z1=x;
z2=(~x)^(0x23333333);
z3=x^(0x12345798);
z4=(~x)+51;
u = 0;
}
}
using namespace GenHelper;
using namespace std;
const int N=2e6+7,mod=1e9+7;
int a[N],b[N];
int main(){
int n,seed;
scanf("%d %d",&n,&seed);
srand(seed);
for(int i=1;i<=n;i++){
a[i]=read(0),b[i]=read(i);
}
// 在此处继续写
return 0;
}
题目给的JAVA代码
import java.util.*;
import java.math.*;
public class Main{
static int z1,z2,z3,z4,z5,u,res;
public static int get(){
z5=((z1<<6)^z1)>>13;
z1=((int)(z1&4294967)<<18)^z5;
z5=((z2<<2)^z2)>>27;
z2=((z2&4294968)<<2)^z5;
z5=((z3<<13)^z3)>>21;
z3=((z3&4294967)<<7)^z5;
z5=((z4<<3)^z4)>>12;
z4=((z4&4294967)<<13)^z5;
return (z1^z2^z3^z4);
}
public static int read(int m){
u=get();
u>>=1;
if(m==0)res=u;
else res=(u/2345+1000054321)%m;;
return res;
}
public static void ssrand(int x){
z1=x;
z2=(~x)^(0x23333333);
z3=x^(0x12345798);
z4=(~x)+51;
u = 0;
}
public static void main(String args[]) {
Scanner in=new Scanner(System.in);
int a[]=new int[2000010];
int b[]=new int[2000010];
int n=in.nextInt(),seed=in.nextInt();
ssrand(seed);
for(int i=1;i<=n;i++){
a[i]=read(0);
b[i]=read(i);
}
// 在此处继续写你的代码
}
}
输入描述

输出描述

样例输入
3 2
样例输出
4
样例说明

思路
先贴一下sjjj的

朕的翻译官呢?
中文汉化版:
- 对于一个新的数组{ 权值, 下标 }, 按权值进行排序
- 在一棵树上记录权值较大的值
- 用DP[k], 来表示前k个中选择方案的最大值
- i从1开始, 一直到n
- 状态转移为 DP[i] = DP[i- 1] - DP[i - 1 - b[i]]
- 但是这里等号右边的DP[k]又是
已经在树上的并且下标在当前下表之前的和 - 最后将当前值插入树
代码
#include<bits/stdc++.h>
namespace GenHelper
{
int z1,z2,z3,z4,z5,u,res;
int get()
{
z5=((z1<<6)^z1)>>13;
z1=((int)(z1&4294967)<<18)^z5;
z5=((z2<<2)^z2)>>27;
z2=((z2&4294968)<<2)^z5;
z5=((z3<<13)^z3)>>21;
z3=((z3&4294967)<<7)^z5;
z5=((z4<<3)^z4)>>12;
z4=((z4&4294967)<<13)^z5;
return (z1^z2^z3^z4);
}
int read(int m) {
u=get();
u>>=1;
if(m==0)res=u;
else res=(u/2345+1000054321)%m;
return res;
}
void srand(int x)
{
z1=x;
z2=(~x)^(0x23333333);
z3=x^(0x12345798);
z4=(~x)+51;
u = 0;
}
}
using namespace GenHelper;
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const int N=2e6+7,mod=1e9+7;
LL a[N],b[N];
int tr[N],f[N];
PII p[N];
int n,seed;
int lowbit(int x) {
return x & -x;
}
void add(int x,int c) {
for(int i=x;i<=n;i+=lowbit(i))
tr[i] = (tr[i] + c)%mod;
}
LL sum(int x) {
LL ans = 0;
for(int i=x;i;i-=lowbit(i))
ans = (ans + tr[i])%mod;
return ans%mod;
}
int main(){
scanf("%d %d",&n,&seed);
srand(seed);
for(int i = 1; i <= n; i ++ ) {
a[i] = read(0), b[i] = read(i);
p[i] = { a[i], i };
}
sort(p + 1, p + n + 1);
for(int i = 1; i <= n; i ++ ) {
int t = p[i].second;
f[t] = (sum(t) - sum(t - 1 - b[t]) + 1 + mod) % mod; // 尤其在做减法的时候要注意取模的问题
add(t, f[t]);
}
cout << sum(n) << endl;
return 0;
}
没有人能比这位老哥更细了/流汗
我在这里吐槽应该不会被发现吧, 狗没那赛
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <limits.h>
#include <vector>
#include <list>
#include <set>
#include <utility> // pair
#include <map>
#include <iostream>
#include <sstream>
#include <algorithm> // sort
#include <functional>
#include <string>
#include <stack>
#include <queue>
#include <fstream>
#include <bitset>
//#include <unordered_map>
//#include <unordered_set>
using namespace std;
#define ll long long
#define lll __int128
#define uchar unsigned char
#define ushort unsigned short
#define uint unsigned int
#define ulong unsigned long
#define ull unsigned long long
#define INT_INF 0x7fffffff
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define memn(a,b,c,n) memset(a,b,sizeof(c)*(n))
#define fre(a) freopen(a,"r",stdin)
#define cio ios::sync_with_stdio(false); // Do not use it with "scanf" and other c input!
#define pb push_back
#define mpair make_pair
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define pre(i,a,b) for(int i=(a);i>=(b);i--)
#define REP(i,a,b) for(int i=(a);i<(b);i++)
#define repl(i,a,b) for(ll i=(a);i<=(b);i++)
#define prel(i,a,b) for(ll i=(a);i>=(b);i--)
#define reada(a,s,n) rep(i,s,n)scanf("%d",a + i);
#define READa(a,s,n) REP(i,s,n)scanf("%d",a + i);
#define readall(a,s,n) rep(i,s,n)scanf("%lld",a + i);
#define READall(a,s,n) REP(i,s,n)scanf("%lld",a + i);
//template <typename _Tp> inline void read(_Tp&x) {
// char ch;bool flag=0;x=0;
// ch=getchar();
// while(!isdigit(ch)){if(ch=='-')flag=1;ch=getchar();}
// while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
// if(flag)x=-x;
//}
//inline void print_lll(lll x) {
// if(x<0) {x=-x;putchar('-');}
// if(x>9) print_lll(x/10);
// putchar(x%10+'0');
//}
//#define _T_(T) int T;scanf("%d",&T);while(T--)
//#define __T _T_(TTESTCASES)
//#define _E_(T) while(~T)
#define __T int TT;scanf("%d",&TT);for (int T = 1;T <= TT;T ++)
#define _C(a) cout << a << endl;
#define dsci(a) int a;scanf("%d",&a)
#define dscii(a,b) int a,b;scanf("%d%d",&a,&b)
#define dsciii(a,b,c) int a,b,c;scanf("%d%d%d",&a,&b,&c)
#define dscl(a) ll a;scanf("%lld",&a)
#define dscll(a,b) ll a,b;scanf("%lld%lld",&a,&b)
#define dsclll(a,b,c) ll a,b,c;scanf("%lld%lld%lld",&a,&b,&c)
#define dscd(a) double a;scanf("%lf",&a)
#define dscdd(a,b) double a,b;scanf("%lf%lf",&a,&b)
#define dscddd(a,b,c) double a,b,c;scanf("%lf%lf%lf",&a,&b,&c)
#define sci(a) scanf("%d",&a)
#define scii(a,b) scanf("%d%d",&a,&b)
#define sciii(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scl(a) scanf("%lld",&a)
#define scll(a,b) scanf("%lld%lld",&a,&b)
#define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define scd(a) scanf("%lf",&a)
#define scdd(a,b) scanf("%lf%lf",&a,&b)
#define scddd(a,b,c) scanf("%lf%lf%lf",&a,&b,&c)
#define lowbit(x) ((x)&(-(x)))
#define Tprint(a,s,e) REP(i,s,e){if(i!=s)printf(" ");printf("%lld",a[i]);}
#define endl '\n'
#define itn int
#define iny int
#define nit int
#define inr int
#define mian main
#define iman main
#define mina main
#define mian main
#define ednl endl
#define fro for
#define fir for
#define reutrn return
#define retunr return
#define reutnr return
#define re0 return 0
#define re1 return 1
//#pragma GCC optimize(2)


浙公网安备 33010602011771号