雅礼集训三十天,day2

发布时间 2023-09-19 08:20:26作者: libohan0518

T1

啊啊啊,很水(要是这题做不出来就退役吧!!)
code:

#include<bits/stdc++.h>

using namespace std;

string a, b;

int main(){
    cin >> a >> b;
    for(int i = 0; i < a.size(); i++){
        if(a[i] != '#'){
            continue;   
        }
        cout << b[a.size() - i - 1];
    }
    return 0;
}

T2

暴搜好吧!!
code:

#include<bits/stdc++.h>

using namespace std;

#define int long long

const int N = 15, MAXN = 1e8 + 5; 

int n, k, a[N], ans, h[N], x[N];

bool vis[MAXN], p[N];


void dfs(int cnt, int sum){
    if(cnt == k + 1){
        if(!vis[sum]){
            vis[sum] = true;
            ans++;
        }
        return ;
    }
    for(int i = 1; i <= n; i++){
        if(!p[i]){
            p[i] = true;
            if(a[i] >= 10){
                dfs(cnt + 1, sum * 100 + a[i]);
            } 
            else{
                dfs(cnt + 1, sum * 10 + a[i]);
            }
            p[i] = false;
        }
    }
}

signed main(){
    cin >> n >> k;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
    }
    dfs(1, 0);
    cout << ans;
    return 0; 
}

T3

没想通很难,呵呵。
其实就是离散化后dp(为数据有1e9那么大)
那么dp策略是什么呢?(我的代码里有注释
code:

#include<bits/stdc++.h>

using namespace std;

#define int long long

const int N = 4e5 + 5, mod = 1e9 + 7;

int k, n, m, hc;

int ls[N], rs[N], lt[N], rt[N], h[N], ms[N], mt[N];

int fs[N], ft[N], g[N], ss[N], st[N], sg[N];

int mypow(int a, int b){//快速幂 
  	int ans = 1;
	while(b){
		if(b & 1){
			ans = ans % mod * a % mod;
		}
		a = a % mod * a % mod;
		b >>= 1;
	}
	return ans;
}

int m1(int x){
    if(x >= mod){
        return x - mod;
    }
    return x;
}

signed main(){
    //后缀带s的是学习
    //后缀带t的是颓废 
    cin >> k >> n >> m; 
    for(int i = 1; i <= n; i++){
        cin >> ls[i] >> rs[i];
        h[++hc] = ls[i] - 1;
        h[++hc] = rs[i];
    }   
    for(int i = 1; i <= m; i++){
        cin >> lt[i] >> rt[i];
        h[++hc] = lt[i] - 1;
        h[++hc] = rt[i];
    }
    h[++hc] = 0;
    h[++hc] = k;
    sort(h + 1, h + hc + 1);
    hc = unique(h + 1, h + hc + 1) - h - 1;//离散化 
    for(int i = 1; i <= n; i++){
        int L = lower_bound(h + 1, h + hc + 1, ls[i] - 1) - h;
        int R = lower_bound(h + 1, h + hc + 1, rs[i]) - h;
        ms[R] = max(ms[R], L + 1);
    }
    for(int i = 1; i <= m; i++){
        int L = lower_bound(h + 1, h + hc + 1, lt[i] - 1) - h;
        int R = lower_bound(h + 1, h + hc + 1, rt[i]) - h;
        mt[R] = max(mt[R], L + 1);
    }
    g[1] = sg[1] = 1;
    ms[1] = mt[1] = 1;
    //ss[i]表示第i个点前面白区间的个数 
    //st[i]表示第i个点前面黑区间的个数 
    //sg[i]表示第i个点前面黑白区间的个数 
    //fs[i]表示以i为R白的区间(也可以理解为第i白个区间)的方案数 
    //ft[i]表示以i为R黑的区间(也可以理解为第i黑个区间)的方案数
    //g[i]表示以i为R黑白的区间(也可以理解为第i黑白个区间)的方案数
    //mt[i]表示在i前面的最大的黑区间的右端点的最大值
    //ms[i]表示在i前面的最大的白区间的右端点的最大值
    for(int i = 2; i <= hc; i++){
        ms[i] = max(ms[i - 1], ms[i]);//离I点最近的白区间的右端点的位置 
        mt[i] = max(mt[i - 1], mt[i]);//离I点最近的黑区间的左端点的位置 
        //白色 
        fs[i] += m1(sg[i - 1] - sg[mt[i] - 1] + mod);//[mt[i] ~ (i - 1)]的黑白方案数 
        fs[i] += m1(st[i - 1] - st[mt[i] - 1] + mod);//[mt[i] ~ (i - 1)]的黑方案数 
        fs[i] = m1(fs[i]);
        //黑色 
        ft[i] += m1(sg[i - 1] - sg[ms[i] - 1] + mod);//[ms[i] ~ (i - 1)]的黑白方案数 
        ft[i] += m1(ss[i - 1] - ss[ms[i] - 1] + mod);//[mt[i] ~ (i - 1)]的白方案数
        ft[i] = m1(ft[i]);
        //黑白 
        g[i] = 1ll * m1(m1(fs[i - 1] + ft[i - 1]) + g[i - 1]) * (mypow(2, h[i] - h[i - 1]) - 2 + mod) % mod;
        //黑白三个都可以配,方案数就是(三个加起来) * (长度为h[i] - h[i - 1]的黑白有多少种摆法) 
        ss[i] = m1(ss[i - 1] + fs[i]);//三个前缀和 
        st[i] = m1(st[i - 1] + ft[i]);
        sg[i] = m1(sg[i - 1] + g[i]);
    }
    cout << m1(m1(fs[hc] + ft[hc]) + g[hc]);//三个加起来
    return 0;
}

T4

就是一个SPFA(或广搜)
搜完以后,将每个点到1点的最大值乘上a[i]转成数位,再4舍5入,再进位即可
code:

#include<bits/stdc++.h>

using namespace std;

#define int long long

const int N = 1e5 + 5;

struct node{
    int v, w;
};

struct dv{
    int d, v;
};

int n, m, a[N], dis[N], val[N];

vector<node> g[N]; 

signed main(){
    cin >> n >> m;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
    }
    for(int i = 1, u, v, w; i <= m; i++){
        cin >> u >> v >> w;
        g[u].push_back({v, w});
    }
    memset(dis, -0x3f, sizeof dis);
    queue<int> q;
    q.push(1);
    dis[1] = 0;
    while(!q.empty()){
        int cur = q.front();
        q.pop();
        for(auto e : g[cur]){
            if(dis[cur] + e.w > dis[e.v]){
                dis[e.v] = dis[cur] + e.w;
                q.push(e.v);
            }
        }
    }
    for(int i = 1; i <= n; i++){
        dis[i] = -dis[i];
    }
    for(int i = 1; i <= n; i++){
        if(dis[i] + 30 >= 0){
            val[dis[i] + 30] += a[i];
        }
    }
    for(int i = 0; i <= 10040; i++){
        val[i + 1] += val[i] / 10, val[i] %= 10;
    }
    if(val[23] >= 5){
        val[24]++;
    } 
    for(int i = 0; i <= 10040; i++){
        val[i + 1] += val[i] / 10, val[i] %= 10;  
    }
    int now = 10040;
    while(val[now] == 0 && now > 30){
        now--;
    }
    for(int i = now; i >= 30; i--){
        cout << val[i];
    }
    cout << ".";
    for(int i = 29; i >= 24; i--){
        cout << val[i];
    }
    return 0;
}

看完要关注哦!!!