2023/6/21---个人总结

C. Game with Reversing

 题目大意:A跟B玩游戏,给定两个字符串,A可以把其中一个字符串中的一个字符换成任意字符, B可以把两个字符串中的一个颠倒。当两个字符串完全相等时,游戏结束,A要尽量缩减时间,B要尽量延长时间,求游戏结束的最短时间。

思路:可以发现B颠倒哪个字符串无关紧要,偶数次等于没翻,奇数次等于翻一次。 设两个字符串正着比有cnt1个不同的,倒着比有cnt2个不同的。 我们只要为cnt1搭配最小偶数次,cnt2搭配最小奇数次,再求最小值即可(cnt1=0和cnt2=0时需要特判一下)。

void solve() {
    int n;
    cin >> n;
    string s1, s2;
    cin >> s1 >> s2;
    int cnt1 = 0, cnt2 = 0;
    for (int i = 0; i < n; i++)if (s1[i] != s2[i])cnt1++;
    for (int i = 0; i < n; i++)if (s1[i] != s2[n - i - 1])cnt2++;
    if (cnt1 == 0) {
        cout << cnt1 << '\n';
        return;
    }
    if (cnt2 == 0) {
        cout << 2 << '\n';
        return;
    }
    if (cnt1 % 2)cnt1 += (cnt1 - 1);
    else cnt1 += cnt1;
    if (cnt2 % 2)cnt2 += cnt2;
    else cnt2 += (cnt2 - 1);
    int ans = min(cnt1, cnt2);
    cout << ans << '\n';
}

C. k-th equality

 题目大意:输入a,b,c,k。a,b,c分别为各自位置上的位数,求满足a+b=c的第k个方案并输出。

思路:枚举a的所有情况,通过c的取值求出b满足条件的区间,即b的最小值和最大值。

typedef long long ll;
void solve() {
    ll a, b, c, k;
    cin >> a >> b >> c >> k;
    ll x = 1, y = 1, z = 1;
    while (--a)x *= 10;
    while (--b)y *= 10;
    while (--c)z *= 10;
    for (ll i = x; i < x * 10; i++) {
        ll l = max(y, z - i);
        ll r = min(y * 10, z * 10 - i);
        if (l > r)continue;
        if (r - l >= k) {
            cout << i << " + " << l + k - 1 << " = " << l + k - 1 + i << '\n';
            return;
        }
        k -= r - l;
    }
    cout << "-1\n";
}

D. Apple Tree

 题目大意:有一颗树,1-n个结点,根结点为1,给定一个n,再给出n-1条边,有两个苹果(苹果会掉落到与它相连并且编号比它小的结点上,若没有则掉落),q次查询,每一次查询给出两个苹果所在的节点x,y,输出有几种掉落方案。

思路:由于每一个结点上的苹果都会在叶子结点掉落,所以只需要找到每一个结点下面有多少个叶子结点即可。c[i]存储每一个结点下面有多少叶子结点(起初均为0),叶子结点下面只有一个叶子结点(本身)。从1开始dfs。

typedef long long ll;
ll c[200010];
vector<int>g[200010];
void dfs(int u, int fa) {
    c[u] = 0;
    int flag = 1;
    for (int i = 0; i < g[u].size(); i++) {
        int v = g[u][i];
        if (v == fa) continue;    //判断是否为叶子结点
        dfs(v, u);
        flag = 0;
        c[u] += c[v];
    }
    if(flag == 1){
        c[u] = flag;
    }
}
void solve() {
    int n;
    int a, b;
    cin >> n;
    for (int i = 0; i < n - 1; i++) {
        cin >> a >> b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    dfs(1,0);
    int q;
    cin >> q;
    while (q--) {
        cin >> a >> b;
        cout << c[a] * c[b] << '\n';
    }
    for (int i = 0; i <= n; i++)vector <int>().swap(g[i]);  //清空
}

预祝端午节快乐!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

akb000

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值