2015-11-06 92 views
0

我在製作一個遊戲,玩家的分數以8,1215的增量遞增。因爲這是一種可以(並且過去曾被黑客入侵)的JavaScript遊戲,所以我需要在向數據庫提交分數之前進行一些服務器端驗證。什麼是C#中的一個很好的算法,用於查找是否存在I,J,K,使得某些S的8 * I + J * 12 + K * 15 = S?

例如,得分3830=2*15+1*8以來有意義,但得分37沒有。例如,912301283 ....的分數,我不確定,因爲我的大腦沒有足夠強大的計算能力。

換句話說,我希望能找出在這種情況下

private static bool scoreAddsUp (int score, int [] incs) 
{ 
    // ... 
} 

其中incs = { 8, 12, 15 }填充的非強力的方式,但當然這將是很好的概括了在此過程我改變了分數增加的方式。

重要的問題:

  • 你有如何從頭開始寫一個算法,這是否使用短蠻力的任何建議?
  • .NET庫是否具有可能對此問題有用的任何函數?
  • 考慮到數字8,1215是我相當隨意選擇的,是否有更好的數字我可以用於此過程?使用素數編號(如7,9,13)是否允許我創建更高效​​的算法?
+0

向服務器發送'i,j,k'並計算得分;對於給定的分數,「i,j,k」不是唯一的:「S = 24」;當'(i,j,k)=(3,0,0)'或'(i,j,k)=(0,2,0)' – ASh

+0

嘗試蠻力攻擊...'O(n^3) '看起來很尷尬,但除非你有很大的數字,否則應該沒問題。 ...順便說一句@如果分數將在形式i,j,k,那麼在檢測中沒有破解...通常黑客被某種類型的CRC檢測......這是一種方式... – Spektre

+3

經過一段時間後,所有整數都可以用該算法表示,所以對於檢測作弊行爲並不是很有用。 – JJJ

回答

0

您可以使用動態規劃

private static Boolean ScoreAddsUp(int score, int[] incs) { 
    HashSet<int> completed = new HashSet<int>(); 

    List<int> frontier = new List<int>() { 
    0 
    }; 

    while (frontier.Any(item => item <= score)) { 
    for (int i = frontier.Count - 1; i >= 0; --i) { 
     int front = frontier[i]; 

     frontier.RemoveAt(i); 
     completed.Add(front); 

     foreach (int inc in incs) { 
     int item = front + inc; 

     if (item == score) 
      return true; 

     if (completed.Contains(item)) 
      continue; 

     frontier.Add(item); 
     } 
    } 
    } 

    return false; 
} 

// Tests 
if (!ScoreAddsUp(29, new int[] { 8, 12, 15 })) 
    Console.Write("Not Found"); 

if (ScoreAddsUp(28, new int[] { 8, 12, 15 })) 
    Console.Write("Found"); 
-3

試試這個:

if (((score % incs[2]) % incs[1]) % incs[0] == 0) 
{ 
    //remining value is 0, correct score 
} 
else 
{ 
    //remining value is not 0, incorrect score 
} 

但是,你應該測試,以確保,不存在假陽性答案

+0

這對'a * i * b * j * c * k'起作用,但對'a * i + b * j + c * k'不起作用。 – JJJ

相關問題