我试图解决这个问题,但自动判断正在返回“超出时间限制”(TLE)。
在情人节之际,亚当和夏娃继续参加比赛。他们全面清理并进入决赛。在最后一轮中,Adam被赋予偶数N和整数K,并且他必须找到小于N的最大奇数M,使得M的二进制表示中的数字之和最多为K.
输入格式:
对于每个测试用例,您将获得偶数
N
和整数K
输出格式:
对于每个测试用例,如果存在,则输出
integer M
,否则输出print -1
约束:
1≤T≤10 4
2≤N≤10 9
0≤K≤30
示例输入:
2
10 2
6 1
示例输出:
9
1
这是我到目前为止所做的。
static long play(long n, int k){
if(k==0) return -1;
if(k==1) return 1;
long m=n-1;
while(m>0){
long value=Long.bitCount(m); //built in function to count bits
if(value<=k ){
return m;
}
m=m-2;
}
return -1;
}
public void solve(InputReader in, OutputWriter out) {
long start=System.currentTimeMillis();
int t=in.readInt();
while(t-->0){
long n=in.readLong();
int k=in.readInt();
long result=play(n,k);
out.printLine(result);
}
long end=System.currentTimeMillis();
out.printLine((end-start)/1000d+"ms");
}
}
答案 0 :(得分:4)
根据更新的问题N
可以在2到10 ^ 9之间。您从N-1
开始并向下循环2,因此您可以进行大约10^9 / 2
次循环迭代。 不好。
从M = N - 1
开始很好。使用bitCount(M)
很好,开始使用。如果最初的bitcount是<= K
,那么你已经完成了。
但如果不是,那么不会循环步骤-2
。
将您心目中的数字视为二进制,例如110101011
。位数为6.假设K为4,这意味着您必须删除2位。最右边的位必须保持打开,并且你想要最大的数字,所以清除两个倒数第二个1位。结果:110100001
。
现在,你弄清楚如何写它。并且无需转换为文本即可完成。
注意:使用N <= 10^9
,它将适合int
。无需long
。
答案 1 :(得分:0)
您必须执行按位操作才能快速计算答案。让我给你一些提示。
数字1的二进制和十进制表示法相同:1 2 = 1 10
要使数字10 2 = 2 10 ,请将1
向左移动一个位置。在Java和许多其他语言中,我们可以这样写:
(1 << 1) == 2
要使二进制数100 2 = 4 10 ,将1
向左移动两个位置:
(1 << 2) == 4
使二进制数1000 2 = 8 10 向左移动1
三个位置:
(1 << 3) == 8
你明白了。
要查看特定位置的位是1还是0,请使用按位AND运算符&
。例如,我们可以确定5 10 = 101 2 在第三个最高有效位为1,在第二个最高有效位为0,在第二个最高有效位为1最重要的一点:
5 & (1 << 2) != 0
5 & (1 << 1) == 0
5 & (1 << 0) != 0
要将位设置为0,请使用按位XOR运算符^
。例如,我们可以将7 10 = 111 2 的第二个最高位设置为0,从而获得5 10 = 101 2 子>:
7 ^ (1 << 1) == 5
答案 2 :(得分:0)
答案很奇怪,
让ans = 1,这里我们使用1位,所以k = k - 1;
现在ans的二进制表示是
ans(binary) = 00000000000000000000000000000001
while(k > 0):
make 30th position set
ans(binary) = 01000000000000000000000000000001
if(ans(decimal) < N):
k -= 1
else:
reset 30th position
ans(binary) = 00000000000000000000000000000001
Do the same from 29th to 1st position