Codeforces 1017B The Bits 题解

本文详细解析 Codeforces 1017B 题目,介绍如何通过分析二进制数 a 和 b 的特性,找出交换 a 中两个位后使得两数按位或运算结果发生变化的所有方案数。

题目链接:

http://codeforces.com/problemset/problem/1017/B

Description

Rudolf is on his way to the castle. Before getting into the castle, the security staff asked him a question:
Given two binary numbers a and b of length n. How many different ways of swapping two digits in a (only in a, not b) so that bitwise OR of these two numbers will be changed? In other words, let c be the bitwise OR of a and b, you need to find the number of ways of swapping two bits in a so that bitwise OR will not be equal to c.
Note that binary numbers can contain leading zeros so that length of each number is exactly n.
Bitwise OR is a binary operation. A result is a binary number which contains a one in each digit if there is a one in at least one of the two numbers. For example, (01010)2 OR (10011)2 = (11011)2.
Well, to your surprise, you are not Rudolf, and you don’t need to help him… You are the security staff! Please find the number of ways of swapping two bits in a so that bitwise OR will be changed.

Input

The first line contains one integer n (2≤n≤10^5) — the number of bits in each number.
The second line contains a binary number a of length n.
The third line contains a binary number b of length n.

Output

Print the number of ways to swap two bits in a so that bitwise OR will be changed.

题目大意:

有两个二进制的数,分别为a、b,假设a or b的值为c,当a中交换两个数后,c的值可能发生变化,求能使c发生变化的方案总数。

提示:

这道题是一道比较简单的思维题,我们仔细寻找规律就可以了。我们可以扫描b这个二进制数。
1. 如果b[i]为1的话,不论它对应的a[i]是0还是1,c[i]一定还是1,所以只用考虑b[i]为0的情况。
2. 当b[i]=0,对应的a[i]=1时,方案总数只要加上a中有的0的个数即可,用a[i]与其交换。
3. 当b[i]=0,a[i]=0时,同样要将它换成1才能达到目的。假设a[j]=1,如果b[j]也等于1,那么可以放心将a[i]与a[j]交换。当a[j]=1,b[j]=0时,那就可以不计入答案了。因为这种情况在第二步中算过了。

所以,只要预处理b[i]==1&&a[i]==1和a[i]==0的个数就可以了。

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 100001
using namespace std;
char a[N],b[N];
int n;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) cin>>b[i];
    int s0=0,s11=0;
    long long ans=0;
    for(int i=1;i<=n;i++)
    {
        if(a[i]=='0') s0++;
        else if(b[i]=='1') s11++;
    }
    for(int i=1;i<=n;i++) if(b[i]=='0')
    {
        if(a[i]=='0') ans+=s11;
        else ans+=s0;
    }
    cout<<ans<<endl;
    return 0;
}

相关链接:

Codeforces 题解小全:
https://blog.youkuaiyun.com/ZJ_MRZ/article/details/81530091

Codeforces 1016A Death Note 题解:
https://blog.youkuaiyun.com/ZJ_MRZ/article/details/81474520

Codeforces 1017A The Rank 题解:
https://blog.youkuaiyun.com/ZJ_MRZ/article/details/81529980

### Codeforces 题目解答思路与方法 #### Monsters and Spells 的解答思路 对于题目 *Monsters And Spells* ,其核心在于模拟怪物受到伤害的过程并判断最终能否击败所有怪物。此过程涉及到贪心算法的应用,具体来说是在每一轮攻击中尽可能多地减少怪物的生命值。 为了实现这一目标,可以先按照怪物初始生命值降序排列,然后依次处理每一个怪物,在每次施放技能时优先选择能造成最大伤害的方式。通过这种方式能够确保在有限的能量下最大化总伤害输出[^1]。 ```cpp #include <bits/stdc++.h> using namespace std; int main() { int t; cin >> t; while(t--) { long long n, h, a, b, k; cin >> n >> h >> a >> b >> k; vector<pair<long long,int>> monsters(n); for(int i = 0; i < n; ++i){ cin >> monsters[i].first; // 生命值 monsters[i].second = i; } sort(monsters.rbegin(), monsters.rend()); // 按照生命值从高到低排序 bool canDefeatAll = true; for(auto& m : monsters) { if(m.first > someFunctionToCalculateDamage(h,a,b,k)){ canDefeatAll = false; break; } } cout << (canDefeatAll ? "YES\n" : "NO\n"); } } ``` 上述代码片段展示了如何读取输入数据并对怪物按生命值进行排序,之后遍历这些已排序的数据来决定是否有可能战胜所有的敌人。 #### Sequence 数字序列生成逻辑分析 针对 *Sequence* 这一问题,则采取了一种完全不同的策略。考虑到直接计算会遇到性能瓶颈以及难以预测的结果模式,转而探索是否存在周期性的特性成为了解决方案的关键所在。经过观察发现随着数值的增长确实出现了重复现象,这意味着一旦找到了这样的循环节就可以快速定位任意位置上的元素而不必逐项构建整个列表[^3]。 ```python def find_nth_number(n): sequence = [] current_num = 1 seen = {} while True: str_form = ''.join(sorted(str(current_num))) if str_form in seen: loop_start_index = seen[str_form] non_loop_part_length = len(sequence[:loop_start_index]) relative_position_within_cycle = (n - non_loop_part_length - 1) % \ (len(sequence) - non_loop_part_length) return int(''.join(sorted(str(sequence[relative_position_within_cycle])))) seen[str_form] = len(sequence) sequence.append(current_num) next_value_options = set([current_num * 2, int(''.join(sorted(str(current_num))))]) current_num = min(next_value_options.difference(set(sequence)), default=current_num + 1) print(find_nth_number(15)) # 输出应为1156 ``` 这段 Python 实现首先尝试建立直到检测到第一个重复项为止的部分序列;接着利用模运算找到给定索引 `n` 对应在环内的确切位置,并据此返回相应的整数值。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值