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)
posted @ 2022-01-26 21:57  哇唔?  阅读(46)  评论(0编辑  收藏  举报