牛客周赛 Round 30

小红构造回文

一开始用了一个很麻烦的写法,找出与第一个字符不同的字符,将这个字符与第一个字符交换。想写法的时候发现很麻烦,需要存下出现过的所有字符和每个字符出现的位置,最后用map套pair实现了。

#include<bits/stdc++.h>

using namespace std;

typedef pair<int, int> PII;

const int N = 1e5 + 7;
string s;
map<char, PII> mp;

void solve(){
    if (mp.size() == 1){
        cout << "-1";
        return;
    } else{
        int t = -1;
        char c;
        for (auto [x, y] : mp){
            if (x != s[0] && y.first >= 2){
                c = x;
                t = y.second;
                break;
            }
        }
        if (t == -1){
            cout << "-1";
            return;
        }
        cout << c;
        for (int i = 1; i < s.size() - 1; i++){
            if (i != t - 1 && i != s.size() - t) cout << s[i];
            else cout << s[0];
        }
        cout << c;
    }
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> s;
    for (int i = 0; i < s.size(); i++) {
        mp[s[i]].first++;
        mp[s[i]].second = i + 1;
    }
    solve();
    return 0;
}

后面看队友的写法发现,直接找到两个相邻的不同字符直接交换就行。

#include<bits/stdc++.h>

using namespace std;

typedef pair<int, int> PII;

void solve(){
    string s;
    cin >> s;
    int n = s.size();
    for (int i = 1; i < n / 2; i++){
        if (s[i] != s[i - 1]){
            swap(s[i], s[i - 1]);
            swap(s[n - i - 1], s[n - i]);
            cout << s;
            return;
        }
    }
    cout << "-1";
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    solve();
    return 0;
}

小红整数操作

不难发现先执行操作二,再执行操作一可以得到最多的可能数。例如x=2,y=4,l=2,r=9时,先将xy同时除2变为x=1,y=2,就能得到三种取值x=2,3,4;y=4,6,8。如果不除只能得到两种取值x=2,4;y=4,8。然后题目需要满足l\leqslant ax\leqslant r,l\leqslant ay\leqslant r,得到\frac{l}{x}\leqslant a\leqslant \frac{r}{x},\frac{l}{y}\leqslant a\leqslant \frac{r}{y}。因为a为整数,所以\frac{l}{x},\frac{l}{y}向上取整,\frac{r}{x},\frac{r}{y}向下取整。因为必须同时满足l\leqslant ax\leqslant r,l\leqslant ay\leqslant r两个条件,所以右边界应该取\frac{r}{x},\frac{r}{y}的最小值,左边界应该取\frac{l}{x},\frac{l}{y}的最大值,取值方案数为左右边界中所有整数。

#include<bits/stdc++.h>

using namespace std;

void solve(){
    int x, y, l, r;
    cin >> x >> y >> l >> r;
    int GCD = __gcd(x, y);
    x /= GCD, y /= GCD;
    int lx = (l + x - 1) / x, rx = r / x, ly = (l + y - 1) / y, ry = r / y;
    cerr << lx << ' ' << rx << ' ' << ly << ' ' << ry;
    int res = min(rx, ry) - max(lx, ly) + 1;
    cout << res;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    solve();
    return 0;
}

小红树上染色

树形DP模板题,和组合类似,需要用乘法。

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;

const int N = 1e5 + 7;
const int P = 1e9 + 7;

vector<int> h[N];
int p[N];
int f[N][2];

void add(int a, int b){
    h[a].push_back(b);
    h[b].push_back(a);
}

void dfs(int u){
    f[u][1] = 1, f[u][0] = 1;
    for (auto x : h[u]){
        if (x == p[u]) continue;
        p[x] = u;
        dfs(x);
        f[u][1] = (ll)f[u][1] * (f[x][0] + f[x][1]) % P;
        f[u][0] = (ll)f[u][0] * f[x][1] % P;
    }
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n; cin >> n;
    for (int i = 1; i < n; i++){
        int a, b;
        cin >> a >> b;
        add(a, b);
    }
    dfs(1);
    int res = (f[1][0] + f[1][1]) % P;
    cout << res;
    return 0;
}

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值