在n个硬币中找到伪造硬币的算法

时间:2016-09-02 07:16:26

标签: algorithm

因此,这是仅使用称重天平在一组硬币中找到伪造硬币的经典问题。为了完整起见,以下是此类问题的一个示例:

  

一个众所周知的例子有九个(或更少)的物品,比如硬币(或球),除了一个之外,它们的重量相同,在这个例子中比其他物品轻 - 一个伪造品(一个古怪的物品)。差异只能通过按比例称重来感知 - 但只有硬币本身才能称重。是否有可能只用两次称重来隔离假币?

我们正在处理的情况是,只有一枚硬币是伪造的,我们知道它是如何的(即我们知道它更重/更轻)。

我的问题是,是否存在一种通用的有效算法来解决具有一个伪造品的let urlString = "relative/path/to/your/index.html" let anchorString = "#your-anchor" let baseURL:NSURL? = NSBundle.mainBundle().URLForResource(urlString, withExtension: nil, subdirectory: nil) if let url:NSURL? = NSURL(string: anchorString, relativeToURL: baseURL) { // Do something with your URL } 硬币的此问题的通用版本。我一直在考虑这个问题,到目前为止,如果N的格式为N,那么您可以通过递归将它们分成三组来找到3^k中的伪造品。这对所有N来说都是如此,而不是来自⌈log_3_(N)⌉的那些,如果是这样,我们能做得更好吗?

4 个答案:

答案 0 :(得分:1)

除非您有关于输入的任何额外信息,否则⌈log_3_(N)⌉是您可以获得的最佳信息。三组相同数量的硬币,两个硬币相互称重,你可以看到三组中哪一组的重量较轻。递归地将相同的算法应用于最轻的组。任何超过k^3的剩余硬币也会保留以供以后轮次使用。

答案 1 :(得分:1)

我们说,你有 N 硬币。

制作3组硬币,每组包含楼层(N / 3)硬币。如果剩余硬币(N%3),请将它们放在最后一个(第3个)组中。请注意,前两组具有相同数量的硬币。

用第2组称量第1组。如果他们不平等,那么我们必须找到其中一个组的罪魁祸首(伪造硬币)。所以我们的解决方案空间在第一次称量后减少到N / 3

如果它们相等,则伪造硬币出现在第三组中,其中最大(N / 3)+2个硬币

以递归方式执行此操作,让我们在ceil(log_3_(N))时间内找到伪造品

答案 2 :(得分:0)

解决假币问题的Javascript代码:

let coins = [3, 2, 3, 3, 3, 3, 3, 3, 3];
let weightUsageCount = 0;
var optimizeUsage = function (coins) {
  let n = coins.length;
  if (n < 1) {
    //If length is lower than 1, no coins are provided
    return -1;
  } else if (n == 1) {
    //If one coin left, it is the lighter coin
    printCoinInfo(coins[0]);
  } else {
    let set1 = coins.slice(0, parseInt(n / 2));
    let set2 = coins.slice(parseInt(n / 2), 2*(n/2));
    let set3 = coins.slice(2*parseInt(n/2), n);

    var coin = diffScale(set1, set2);
    if (coin == 0) {
      //Set 1 is lighter
      optimizeUsage(set1);
    } else if (coin == 1) {
      //Set 2 is lighter
      optimizeUsage(set2);
    } else {
      //Balanced
      optimizeUsage(set3);
    }
  }
};


var diffScale = function (coinSet1, coinSet2) {
  weightUsageCount++;
  let sum1 = coinSet1.reduce((a, b) => a + b, 0);
  let sum2 = coinSet2.reduce((a, b) => a + b, 0);
  
  if (sum1 < sum2) return 0;
  else if (sum2 < sum1) return 1;
  return -1;
};

var printCoinInfo = function(coin) {
  console.log("Array : "+JSON.stringify(coins)+ " | Total Coins : "+coins.length);
  console.log("Defect Coin Weight : "+coin);  
  console.log("Weight Scale Usage : "+ weightUsageCount+" Times");
}

optimizeUsage(coins);

在此处查看 JSFiddle 演示:https://jsfiddle.net/ShashiBadhuk/odtyms5g/

答案 3 :(得分:-1)

我已经使用过这段代码了,但有时它会被1((

I'm a.