在进行检查时,这是任务之一(我无法解决):
他们说A"舒适"如果将两个数字转换为二进制数字,则B中所有位数为1的位置必须是A中相同位置的另一个数字。
示例:
B = 101 A = 111
在这种情况下,数字A"舒适"然而,到B,
B = 101 A = 011
不符合舒适条件。
他们给了我3个无符号数字,其中30位A,B和C,介于0和2 ^ 30之间。我必须确定该范围内符合"舒适度"至少有一个这样的数字。
预期的最坏情况时间复杂度为O(log(A)+ log(B)+ log(C));
我使用以下代码并且花费的时间太长,最重要的是因为它将二进制数检查为数组并比较每个单元格。我认为必须有一些方法可以让它更快(一些数学运算或idk :-()。
public class Main {
public static void main(String[] args)
{
sol(905,5000,11111111); //I used any numbers
}
public static void sol(int A, int B, int C)
{
int min=Math.min(A, Math.min(B, C));
int max=(int) Math.pow(2, 30);
String binA=Integer.toBinaryString(A); binA=fillBin(binA);
String binB=Integer.toBinaryString(B); binB=fillBin(binB);
String binC=Integer.toBinaryString(C); binC=fillBin(binC);
String binMax=Integer.toBinaryString(max);
int conta=0;
for(int i=min;i<=max;i++)
{
String binT = Integer.toBinaryString(i);binT=fillBin(binT);
boolean failA=false;
boolean failB=false;
boolean failC=false;
for(int j=0;j<binT.length();j++)
{
if((binA.length()<j)&&(binB.length()<j)&&(binC.length()<j))
{
break;
}
if((!failA)||(!failB)||(!failC))
{
if((binA.length()<j)&&(binA.charAt(j)=='1') && (binT.charAt(j)!='1'))
{
failA=true;
}
if((binB.length()<j)&&(binB.charAt(j)=='1') && (binT.charAt(j)!='1'))
{
failB=true;
}
if((binC.length()<j)&&(binC.charAt(j)=='1') && (binT.charAt(j)!='1'))
{
failC=true;
}
}
else
{
break;
}
}
if((!failA)||(!failB)||(!failC))
{
conta++;
}
}
}
private static String fillBin(String binA)
{
String S=binA;
for(int i=0;i<(31-binA.length());i++)
{
S="0"+S;
}
return S;
}
}
如果您之前已经完成此任务并且发现有一些缺失的数据,请告诉我,原谅我的英语(不是我的母语)。
非常感谢
编辑:这是@Eran帮助下的代码:
public class BinaryTask
{ public void test(int A,int B,int C) { long timeStart,timeEnd; timeStart = System.currentTimeMillis();
//Bunch of variables
String binaryA = Integer.toBinaryString(A); int zerosA=0;
String binaryB = Integer.toBinaryString(B); int zerosB=0;
String binaryC = Integer.toBinaryString(C); int zerosC=0;
String binaryAB =""; int zerosAB=0;
String binaryBC =""; int zerosBC=0;
String binaryAC =""; int zerosAC=0;
String binaryABC=""; int zerosABC=0;
//The long for the for
int Max = Math.max(binaryA.length(), Math.max(binaryB.length(), binaryC.length()));
//Creating: A|B, B|C, A|B and A|B|C that meet the confort condition
for(int i=0;i<Max;i++)
{
//Creating A|B
if((binaryA.length()>i)&&(binaryB.length()>i))
{
if((binaryA.charAt(i)=='1')||(binaryB.charAt(i)=='1'))
{
binaryAB="1"+binaryAB;
}
else //I also count this zero so i dont have the do another for later
{
binaryAB="0"+binaryAB; zerosAB++;
}
}
//Creating B|C
if((binaryB.length()>i)&&(binaryC.length()>i))
{
if((binaryB.charAt(i)=='1')||(binaryC.charAt(i)=='1'))
{
binaryBC="1"+binaryBC;
}else{binaryBC="0"+binaryBC; zerosBC++;}
}
//Creating A|C
if((binaryA.length()>i)&&(binaryC.length()>i))
{
if((binaryA.charAt(i)=='1')||(binaryC.charAt(i)=='1'))
{
binaryAC="1"+binaryAC;
}else{binaryAC="0"+binaryAC;zerosAC++;}
}
//Creating A|B|C
if((binaryA.length()>i)&&(binaryB.length()>i)&&(binaryC.length()>i))
{
if((binaryA.charAt(i)=='1')||(binaryB.charAt(i)=='1')||(binaryC.charAt(i)=='1'))
{
binaryABC="1"+binaryABC;
}else{binaryABC="0"+binaryABC; zerosABC++;}
}
}
//Counting the other amount of zeros
zerosA = countZeros(binaryA);
zerosB = countZeros(binaryB);
zerosC = countZeros(binaryC);
long confortA = (long) Math.pow(2, zerosA);
long confortB = (long) Math.pow(2, zerosB);
long confortC = (long) Math.pow(2, zerosC);
long confortAB = (long) Math.pow(2, zerosAB);
long confortBC = (long) Math.pow(2, zerosBC);
long confortAC = (long) Math.pow(2, zerosAC);
long confortABC = (long) Math.pow(2, zerosABC);
long totalConfort = confortA + confortB + confortC - confortAB - confortBC - confortAC + confortABC;
timeEnd = System.currentTimeMillis();
System.out.println("Total of confort for A "+A+" B "+B+" C "+C+" is " +totalConfort);
System.out.println("the task has taken "+ ( timeEnd - timeStart ) +" milliseconds");
}
private int countZeros(String binary)
{
int count=0;
for(int i=0;i<binary.length();i++)
{
if(binary.charAt(i)=='0')
{count++;}
}
return count;
}
}
为了进行测试,我做了这个:
public static void main(String[] args)
{
BinaryTask T = new BinaryTask();
int A = (int) Math.pow(2, 10);
int B = (int) Math.pow(2, 15);
int C = (int) Math.pow(2, 30);
T.test(A, B, C);
}
这就是输出:
A 1024 B 32768 C 1073741824的总配额是1073739776 任务花了1毫秒
答案 0 :(得分:3)
在@ alain的答案的基础上,comf(A) = 2^(number of zero bits in A)
是A的安慰数字。
您需要A,B或C的舒适数字。
那是comf(A)+comf(B)+comf(C)-comf(A and B)-comf(B and C)-comf(A and C)+comf(A and B and C)
。
其中comf(A and B)
表示A和B的舒适数字数。
comf(A and B and C)
表示所有A,B和C的安慰数。
我们知道如何计算comf(A)
,comf(B)
和comf(C)
。
comf(A and B) = 2^(number of zero bits in A|B)
,因为当且仅当A或B中的A或B都有1时,数字X才安慰A和B.
同样,comf(A and B and C) = 2^(number of zero bits in A|B|C)
。
由于所有计算都是A
,B
和C
上的位操作,因此运行时间是A
,B
和C
,O (log (A) + log (B) + log (C))
。
答案 1 :(得分:1)
'对B的安慰'的条件是
B & A == B
您可以只计算n
中0
位B
的数量,然后您有2^n
或Math.pow(2, n)
种可能来构建'慰借' 1号}}。
不幸的是,这不适用于“至少安慰三个数字中的一个”,但它可能是一个起点。
答案 2 :(得分:0)
您确定A 1024 B 32768 C 1073741824的输出总容量是否为1073739776是否正确? 我确实同意按位操作,因为我得到了不同的改动btw。
public static int solution(int A,int B,int C){
int total = 0;
int totalA=0,totalB=0,totalC=0;
//int max = Math.max(Math.max(A, B), C);
double limit = Math.pow(2,30);
for(int i=0;i<=limit;i++){
int no = A & i;
if(no == A){
total++;
totalA++;
//continue;
}
no = B & i;
if(no == B){
total++;
totalB++;
//continue;
}
no = C & i;
if(no == C){
total++;
totalC++;
//continue;
}
}
System.out.println("totalA: " + totalA + " totalB: " + totalB + " totalC: " + totalC);
total = totalA + totalB + totalC;
return total;
}
它给了我totalA:536870912 totalB:536870912 totalC:1 1073741825