给定两个正整数a和b,您必须通过对a的二进制形式应用这三个操作中的任何一个来将a更改为b。您可以从a的二进制形式中选择ai和aj(i!= j的任何两个位),然后执行以下操作:
- AND运算为:temp = ai&aj,ai = temp&ai,aj = temp&aj
- 或运算为:temp = ai | aj,ai = temp | ai,aj = temp | j
- XOR运算为:temp = ai ^ aj,ai = temp ^ ai,aj = temp ^ aj
其中&=按位与,| | = bitwiese或,^ =按位XOR。
找到将a转换为b所需的最小操作。另外,如果无法将a转换为b,则打印-1。
例子:
Input : a = 12 (1100), b = 10 (1010)
Output : 1
Explanation : select a2 and a3 and perform XOR
Input : a = 15 (1111), b = 10 (1010)
Output : -1
Explanation : Conversion from a to b is not possible
说明:首先,让我们了解这三个操作的工作原理。
- AND运算为:temp = ai&aj,ai = temp&ai,aj = temp&aj
如果ai或aj中的任何一个为0,则将两者都设为0,否则对ai和aj没有影响。
- 或运算为:temp = ai | aj,ai = temp | ai,aj = temp | j
如果ai或aj中的任何一个为1,则两者都为1,否则对ai和aj没有影响。
- XOR运算为:temp = ai ^ aj,ai = temp ^ ai,aj = temp ^ aj
只需互换ai和aj的值即可。
根据运营工作得出的一些结论:
- 如果a的所有位均为1或0,则我们无法更改a的值。
- 如果a等于b,则不需要任何操作。
- 令n为索引i的数量,其中ai = 0且bi = 1。
令m为索引i的数量,其中ai = 1,bi = 0。让我们考虑n个元素,其中ai = 0和bi =1。我们必须将所有这些零更改为1。请注意,这至少需要进行n次操作。
类似地,对于所有m个元素,其中ai = 1和bi =0。我们必须将所有这些元素都更改为零。请注意,这至少需要进行m次操作。令res = max(n,m)。我们可以使a和b在res运算中相等,如下所示。
令n> = m。取A中的m 1和n 0,然后应用XOR操作将0与1交换。之后,您将剩下的总nm零元素更改为1。您可以通过将这些零中的每一个与单个零相乘并应用“或”运算来实现。
令m> = n。取A中的m 1和n 0,然后应用XOR操作将0与1交换。之后,您将剩下的总数mn个元素变为零。您可以通过将每个这些取一个单个零并应用“或”运算来实现。
// Cpp program to find min operation to convert a to b
#include
using namespace std;
// function to return min operation
int minOp(bitset<32> a1, bitset<32> b1)
{
// if a1 == b1 return 0
if (a1 == b1)
return 0;
// if all bits of a = 0
if (a1 == 0)
return -1;
// if all bits of a =1
// first convert a1 to int and then cal a1 & a1+1
if (((int)a1.to_ulong() & ((int)a1.to_ulong() + 1))
== 0)
return -1;
// convert a and b to binary string
string a = a1.to_string();
string b = b1.to_string();
// check where ai and bi are different
// and count n where ai = 1 and m where ai = 0
int n = 0, m = 0;
for (int i = 0; i < b.size(); i++) {
if (b[i] != a[i]) {
if (a[i] == '1')
n++;
else
m++;
}
}
// return result
return max(n, m);
}
// driver program
int main()
{
bitset<32> a = 14, b = 1;
cout << minOp(a, b);
return 0;
}
输出:
3