試題 算法訓練 Bit Compressor算法
資源限制
時間限制:1.0s 內存限制:256.0MB
問題描述
數據壓縮的目的是爲了減小存儲和交換數據時出現的冗餘。這增長了有效數據的比重並提升了傳輸速率。有一種壓縮二進制串的方法是這樣的:
將連續的n個1替換爲n的二進制表示(注:替換髮生當且僅當這種替換減小了二進制串的總長度)
(譯者注:連續的n個1的左右必須是0或者是串的開頭、結尾)
好比:11111111001001111111111111110011會被壓縮成10000010011110011。原串長爲32,被壓縮後串長爲17.
這種方法的弊端在於,有時候解壓縮算法會獲得不止一個可能的原串,使得咱們沒法肯定原串到底是什麼。請你寫一個程序來斷定咱們可否利用壓縮後的信息來肯定原串。給出原串長L,原串中1的個數N,以及壓縮後的串。
L<=16 Kbytes,壓縮後的串長度<=40 bits。
輸入格式
第一行兩個整數L,N,含義同問題描述
第二行一個二進制串,表示壓縮後的串
輸出格式
輸出"YES"或"NO"或"NOT UNIQUE"(不包含引號)
分別表示:
YES:原串惟一
NO:原串不存在
NOT UNIQUE:原串存在但不惟一
樣例輸入
樣例1:
32 26
10000010011110011
樣例2:
9 7
1010101
樣例3:
14 14
111111
樣例輸出
樣例1:YES
樣例2:NOT UNIQUE
樣例3:NO數組
Java代碼:spa
public class Main { // 原字符串長 private static int L; // 原字符串1的個數 private static int N; // 壓縮後的字符串 private static String str; // 知足條件的原字符串個數 private static int count; public static void main(String[] args) { Scanner input = new Scanner(System.in); L = input.nextInt(); N = input.nextInt(); str = input.next(); division(0, 0, 0); if (count > 1) { System.out.println("NOT UNIQUE"); } else if (count < 1) { System.out.println("NO"); } else { System.out.println("YES"); } } /** * 32 26 * 10000010011110011 * @param curIndex 當前壓縮後字符串的索引 * @param curStrLen 當前字符串的長度 * @param curOneNum 當前字符串中1的個數 */ public static void division(int curIndex, int curStrLen, int curOneNum) { // 出口 if (curIndex == str.length()) { if (curStrLen == L && curOneNum == N) { count++; } return; } if (curStrLen > L) { return; } if (curOneNum > N) { return; } // 第一個開始字符是1的話,那麼就從這個1開始,向後依次遍歷 if (str.charAt(curIndex) == '1') { for (int i = curIndex; i < str.length(); i++) { // 若是是「1xxxx1」則不用判斷,必定沒有這種狀況 /* 根據題意:能壓縮的只有三種狀況 一、111110 二、011110 三、011111 */ // 開頭和結尾都是1那麼就直接跳過這種狀況 if (i + 1 < str.length() && str.charAt(i + 1) == '1') { continue; } int n = getD(str.substring(curIndex, i + 1)); // 注意 「11」 的原字符串多是 「111」 或者 「11」 因此n = 3時要多分一種狀況 /* 若是長度爲3,原串多是111 但若是原串是11,就不須要轉換他 因此咱們不清楚結果中的11是通過轉換的,仍是說原來就是這樣的 因此分兩種狀況: */ if (n == 3) { // 原串爲「11」 division(i + 1, curStrLen + 2, curOneNum + 2); } division(i + 1, curStrLen + n, curOneNum + n); } } else { // 若是第一個字符不是1,而是零,則直接指針向後移一位,當前字符串的長度+1 division(curIndex + 1, curStrLen + 1, curOneNum); } } /** * 返回對應二進制數的十進制數 * @param binStr * @return */ public static int getD(String binStr) { int total = 0; for (int i = 0; i < binStr.length(); i++) { if (binStr.charAt(i) == '1') { total += (long) Math.pow(2, (binStr.length() - 1 - i)); } } return total; } }