【问题标题】:Multiplying Using Bitwise Shift Operators Giving TLE使用提供 TLE 的按位移位运算符进行乘法
【发布时间】:2017-12-29 18:10:11
【问题描述】:

Question

给定 NM,使用左移运算符编写一个方程 结果将等于乘积 N * M

输入:第一行有 0 T ≤ 50000 表示测试用例的数量。
接下来 T 行有两个整数 0 N, M ≤ 10¹⁶。

输出:为每个测试用例打印一个等式 N * M 类似

(N 其中 p1 ≥ p2 ≥ ... ≥ pk k 是最小值。

SAMPLE INPUT    SAMPLE OUTPUT

2
2 1             (2<<0)
2 3             (2<<1) + (2<<0)

时间限制:1.0 秒

我的解决方案第一种方法

int dig = (int)(Math.floor(Math.log10(m)/Math.log10(2))+1);
boolean flag = false;
for(long i = dig; i>=0; --i) {       
      if(((m>>(i-1l)) & 1l) == 1l) {
           if(flag)
               System.out.print(" + ("+n+ "<<"+(i-1)+")");
           else {
               System.out.print("("+n+"<<"+(i-1)+")");
               flag = true; 
                }
             } 
         }

第二种方法

boolean[] arr = new boolean[dig];
        int i = dig-1;
        while(m > 0) {
            if((m&1) == 1 ) {
                arr[i] = true;
            }
            i--;
            m = m>>1l;
        }
        int j = dig-1;
        for( i = 0; i < dig; ++i) {

            if(arr[i]) {
               if(flag) 
               System.out.print(" + ("+n+"<<"+j+")");
               else {
                   System.out.print("("+n+"<<"+j+")");
                   flag = true;
               }
            }

            j--;
        }

在这两种情况下,我都得到了 8 个正确的 5 个,其余 3 个是 TLE,为什么?

【问题讨论】:

  • «TLE»是什么意思?
  • 已超过时间限制。每个查询的接受时间为 1.0 秒
  • 如果是(使用左移运算符,写)(一个方程),它似乎使用的是m&gt;&gt;,而不是&lt;&lt;。如果没有 any 指示 m ,我们如何知道 m&gt;&gt; 是否没有扩展 ms 符号,m 永远不会达到 0 Second Approach?也就是说,我不知道为什么第一个应该 TLE - 第二个应该得到 IOOBE。我没有看到你的 sn-ps 输出 lines。我确实看到很多“字符串添加”的参数在迭代之间没有改变。
  • @greybeard IOOBE?这是否意味着IndexOutOfBoundsException?现在可以做些什么来改进它?我不完全明白你想说什么。 “m”是我们除以 n 的数。例如 2 * 3,然后 n = 2 和 m = 3。所以我将其分解为二进制的 3 = 11。我必须将 2 位移 1,然后将其添加到位移 2 中。如果它是 m = 2,那么我不会将 2 位移添加 0。

标签: java bit-manipulation bit-shift multiplication


【解决方案1】:

实际上,我在您的两种方法中都看不到任何东西,可以在一秒钟内将数万个高达 57 位的数字乘积表示为 Strings:
TLE 可能 是因为 System.out.print() 花费了过多的时间。
也就是说,使用像

这样的实用程序
   /** builds <code>n * m</code> in the form
    * <code>(n&lt;&lt;p1) + (n&lt;&lt;p2) + ... + (n&lt;&lt;pk)</code>
    * using left shift.
    * @param n  (0 < multiplicand <= 10**16)
    * @param m  0 < multiplier <= 10**16
    * @return a verbose <code>String</code> for <code>n * m</code>
    */
    static String verboseBinaryProduct(Object n, long m) {
        int shift = Long.SIZE - Long.numberOfLeadingZeros(m) - 1;
        final long highest = 1 << shift;
        final StringBuilder binary = new StringBuilder(42);
        final String chatter = ") + (" + n + "<<";
        final long rest = highest - 1;
        while (true) {
            if (0 != (highest & m))
                binary.append(chatter).append(shift);
            if (0 == (rest & m)) {
                binary.append(')');
                return binary.substring(4);
            }
            m <<= 1;
            shift -= 1;
        }
    }

System.out.println(verboseBinaryProduct(n, m));

【讨论】:

  • @greybeard 很抱歉,您最后的第三个案例是错误答案,最后两个是运行时错误(NZEC)。请检查一下。
  • your third last case is the wrong answer我的?我没有试图让hackerearth接受提交。也就是说,与记下两个“测试用例”(总共三个)在工作中看到一个错误相比,我启动 IDE 花费的时间更长。 last two are [NonZeroExitCode]我没有提出main(),没有打电话给System.exit(~0)。 (如果hackerearth在不透露电子邮件地址的情况下接受了提交,我可能尝试使用输出(&,可能是输入)缓冲,以及其他两种方法。 )
猜你喜欢
  • 1970-01-01
  • 2011-04-12
  • 1970-01-01
  • 2022-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多