1. 程式人生 > >華農oj Problem K: 負2進制【有技巧構造/待補】

華農oj Problem K: 負2進制【有技巧構造/待補】

第一條 表示 NPU GC spa mem esp 就是 sample

Problem K: 負2進制
Time Limit: 2 Sec  Memory Limit: 128 MB
Submit: 51  Solved: 6
[Submit][Status][Web Board]
Description
如果我16歲,我可以悄悄的說我好喜歡你;如果我26歲,我可以大聲告訴你我很愛你;可惜我6歲,我什麽都給不了你,我還要上小學。

 

我們都知道2進制,每一位的權值如下:

1 2 4 8 16 32 64

現在我們定義一種-2進制,每一位的權值如下:

1 -2 4 -8 16 -32 64

現在我們給一個正數x,用-2進制表示,輸出ceil(x/2),用-2進制表示。

什麽是ceil(x)?     ceil(x)就是對x向上取整。

什麽是對x向上取整 ?     向上取整就是取≥x的最小整數

什麽是≥ ? 就是不小於

什麽是不小於? 呵呵

Input
第一行為T代表有T組樣例.(T<=20)

接下來有T行,每一行有一個用-2進制表示的正數(保證是正數且位數不超過5*10^5)

Output
對於每組測試輸出一行,每行代表一個用-2進制表示的ceil(x/2).(註意不含前導0)

Sample Input
2
10101
10100
Sample Output
11111
11110
HINT

10101 用10進制表示是 21 , ceil(21/2) = 11


10100 用10進制表示是 20 , ceil(20/2) = 10 


註意不要輸出前導0
[Submit][Status]

OJ地址

10 -> 11,  002 -> 110, 12 -> 00
第一條是 ceil(x/2) 的變化,後面兩條是為了消除 2
---
推出結論,除以2相當於把原來二進制數的每一位變成這一位與後一位都加上1,而第0位不變即可,於是得到新的二進制數,可能存在一些位為2,而這些位可與前面的一位消去,消去後就是答案
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double eps = 1e-7;
const int maxn = 5e5 + 5;
const double pi = acos(-1.0);
char a[maxn];
int b[maxn];
int main(int argc, char const *argv[]) {
  int t;
  std::cin >> t;
  while(t--)
  {
    memset(b,0,sizeof(b));
    scanf("%s", &a);
    int len = strlen(a);
    for(int i = 0; i < len - 1; i++) {
      if(a[i] =='1') {
        b[i]++;
        b[i+1]++;
      }
    }
    if(a[len-1]=='1') {
      b[len-1]++;
    }
    for(int i = len - 1; i >= 0; --i) {
      if(b[i] >= 2) {
        if(b[i-1] >= 1) {
          b[i-1]--;
          b[i] -= 2;
        }
        else{
          b[i-1]++;
          b[i-2]++;
        }
      }
    }
    int k = 0;
    while (b[k]==0) {
      k++;
    }
    while(k < len) {
      std::cout << b[k];
      k++;
    }
    std::cout << '\n';
  }
  return 0;
}

華農oj Problem K: 負2進制【有技巧構造/待補】