uvalive 6300 Signed Binary Representation of Integers

6300 Signed Binary Representation of Integers
Computing a
x mod n for large integers x and n is the most time-consuming process in most public-key
cryptography systems. An algorithm to compute a
x mod n can be described in a C-like pseudo-code as
follows.
Input: positive integers a, x and n,
Output: y = a
x mod n
Method:
convert x into binary (xk−1xk−2 . . . x0)2;
y = 1;
for (i = k − 1;i ≥ 0;i = i − 1) {
y = y
2 mod n;
if (xi == 1)y = y × a mod n;
}
print y;
In the above algorithm, first x is converted into k-bit binary. Then the algorithm performs k
iterations. In each iteration, a square (y
2 mod n) is computed. In the i-th iteration, if xi = 1, the
algorithm also computes y = y × a mod n. Therefore, the computing time depends on the number of
1’s in the binary representation of x.
Let a
−1 be the inverse of a in the group Z

n
. That is a × a
−1 ≡ 1 mod n. For example, assume that
n = 13, then the inverse of 2 is 7, 2 × 7 = 14 ≡ 1(mod13). In this problem, you do not need to know
how to compute the inverses.
Assume that a
−1
is known, and x is represented by -1, 0, 1, instead of 0, 1, we can modify the above
algorithm as follows.
Input: positive integers a, x and n,
Output: y = a
x mod n
Method:
convert x into signed binary (xk−1xk−2 . . . x0)−1,0,1;
y = 1;
for (i = k − 1;i ≥ 0;i = i − 1) {
y = y
2 mod n;
if (xi == 1)y = y × a mod n;
if (xi == −1)y = y × a
−1 mod n;
}
print y;
In the above algorithm, we need to represent x by using -1, 0, 1. This is called signed binary
representation of x. For convenience, we shall use 1 to denote -1. For example: 15 = (1111)2 =
(10001)−1,0,1.
You can see that it may be more efficient to use signed binary representation in computing a
x mod n
when the inverse of a (a
−1 mod n) is known. For x = 15, using binary needs 4 multiplications, while
using signed binary needs only 2.ACM-ICPC Live Archive: 6300 – Signed Binary Representation of Integers 2/2
In this problem, you are going to write a program to convert a large integer into signed binary.
Signed binary representation of an integer may not be unique. We need a representation with minimum
number of non-zero bits to make the computation of a
x mod n fast.
A hint of converting x into a signed binary with minimum number of non-zero bits: Make sure that
no adjacent two bits are both non-zero.
Input
The input to this problem is a sequence of large integers. Each integer x is no more than 120 decimal
digits, and it is written in a line. There will be no spaces in front of x, and no spaces after x. The last
line of the input file contains a single ‘0’. You do not need to process this line.
Output
The outputs for each test case consists of two parts written in one line. The first part is an integer b,
which is the number of non-zero bits of the binary representation of x. The second part is an integer s,
which is the number of non-zero bits in the signed binary representation of x. Print exactly one space
between these two parts.
Sample Input
15
2514593
113113561845
0
Sample Output
4 2
11 9
23 14

思路:假如是 111 那么就可以转成 100(-1),对于连续的k(k>=2)个1,我们也可以像那么转化。

每次转化可以减少 k-2个非0

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<cmath>
#include<queue>
#include<cstring>
#include<set>
#include<stack>
#include<string>
#include<ctime>
#define LL long long
#define u64 unsigned long long
#define maxn 100010
#define INF 0x3f3f3f3f
#define eps 1e-6
using namespace std;
#define MAXN 9999
#define MAXSIZE 1000
#define DLEN 4

class BigNum
{
private:
    int a[MAXSIZE];    //可以控制大数的位数
    int len;       //大数长度
public:
    BigNum(){ len = 1;memset(a,0,sizeof(a)); }   //构造函数
    BigNum(const int);       //将一个int类型的变量转化为大数
    BigNum(const char*);     //将一个字符串类型的变量转化为大数
    BigNum(const BigNum &);  //拷贝构造函数
    BigNum &operator=(const BigNum &);   //重载赋值运算符,大数之间进行赋值运算

    friend istream& operator>>(istream&,  BigNum&);   //重载输入运算符
    friend ostream& operator<<(ostream&,  BigNum&);   //重载输出运算符

    BigNum operator+(const BigNum &) const;   //重载加法运算符,两个大数之间的相加运算
    BigNum operator-(const BigNum &) const;   //重载减法运算符,两个大数之间的相减运算
    BigNum operator*(const BigNum &) const;   //重载乘法运算符,两个大数之间的相乘运算
    BigNum operator/(const int   &) const;    //重载除法运算符,大数对一个整数进行相除运算

    BigNum operator^(const int  &) const;    //大数的n次方运算
    int    operator%(const int  &) const;    //大数对一个int类型的变量进行取模运算
    bool   operator>(const BigNum & T)const;   //大数和另一个大数的大小比较
    bool   operator>(const int & t)const;      //大数和一个int类型的变量的大小比较

    void print();       //输出大数
};
BigNum::BigNum(const int b)     //将一个int类型的变量转化为大数
{
    int c,d = b;
    len = 0;
    memset(a,0,sizeof(a));
    while(d > MAXN)
    {
        c = d - (d / (MAXN + 1)) * (MAXN + 1);
        d = d / (MAXN + 1);
        a[len++] = c;
    }
    a[len++] = d;
}
BigNum::BigNum(const char*s)     //将一个字符串类型的变量转化为大数
{
    int t,k,index,l,i;
    memset(a,0,sizeof(a));
    l=strlen(s);
    len=l/DLEN;
    if(l%DLEN)
        len++;
    index=0;
    for(i=l-1;i>=0;i-=DLEN)
    {
        t=0;
        k=i-DLEN+1;
        if(k<0)
            k=0;
        for(int j=k;j<=i;j++)
            t=t*10+s[j]-‘0‘;
        a[index++]=t;
    }
}
BigNum::BigNum(const BigNum & T) : len(T.len)  //拷贝构造函数
{
    int i;
    memset(a,0,sizeof(a));
    for(i = 0 ; i < len ; i++)
        a[i] = T.a[i];
}
BigNum & BigNum::operator=(const BigNum & n)   //重载赋值运算符,大数之间进行赋值运算
{
    int i;
    len = n.len;
    memset(a,0,sizeof(a));
    for(i = 0 ; i < len ; i++)
        a[i] = n.a[i];
    return *this;
}
istream& operator>>(istream & in,  BigNum & b)   //重载输入运算符
{
    char ch[MAXSIZE*4];
    int i = -1;
    in>>ch;
    int l=strlen(ch);
    int count=0,sum=0;
    for(i=l-1;i>=0;)
    {
        sum = 0;
        int t=1;
        for(int j=0;j<4&&i>=0;j++,i--,t*=10)
        {
            sum+=(ch[i]-‘0‘)*t;
        }
        b.a[count]=sum;
        count++;
    }
    b.len =count++;
    return in;

}

BigNum BigNum::operator+(const BigNum & T) const   //两个大数之间的相加运算
{
    BigNum t(*this);
    int i,big;      //位数
    big = T.len > len ? T.len : len;
    for(i = 0 ; i < big ; i++)
    {
        t.a[i] +=T.a[i];
        if(t.a[i] > MAXN)
        {
            t.a[i + 1]++;
            t.a[i] -=MAXN+1;
        }
    }
    if(t.a[big] != 0)
        t.len = big + 1;
    else
        t.len = big;
    return t;
}
BigNum BigNum::operator-(const BigNum & T) const   //两个大数之间的相减运算
{
    int i,j,big;
    bool flag;
    BigNum t1,t2;
    if(*this>T)
    {
        t1=*this;
        t2=T;
        flag=0;
    }
    else
    {
        t1=T;
        t2=*this;
        flag=1;
    }
    big=t1.len;
    for(i = 0 ; i < big ; i++)
    {
        if(t1.a[i] < t2.a[i])
        {
            j = i + 1;
            while(t1.a[j] == 0)
                j++;
            t1.a[j--]--;
            while(j > i)
                t1.a[j--] += MAXN;
            t1.a[i] += MAXN + 1 - t2.a[i];
        }
        else
            t1.a[i] -= t2.a[i];
    }
    t1.len = big;
    while(t1.a[t1.len - 1] == 0 && t1.len > 1)
    {
        t1.len--;
        big--;
    }
    if(flag)
        t1.a[big-1]=0-t1.a[big-1];
    return t1;
}

BigNum BigNum::operator*(const BigNum & T) const   //两个大数之间的相乘运算
{
    BigNum ret;
    int i,j,up;
    int temp,temp1;
    for(i = 0 ; i < len ; i++)
    {
        up = 0;
        for(j = 0 ; j < T.len ; j++)
        {
            temp = a[i] * T.a[j] + ret.a[i + j] + up;
            if(temp > MAXN)
            {
                temp1 = temp - temp / (MAXN + 1) * (MAXN + 1);
                up = temp / (MAXN + 1);
                ret.a[i + j] = temp1;
            }
            else
            {
                up = 0;
                ret.a[i + j] = temp;
            }
        }
        if(up != 0)
            ret.a[i + j] = up;
    }
    ret.len = i + j;
    while(ret.a[ret.len - 1] == 0 && ret.len > 1)
        ret.len--;
    return ret;
}
BigNum BigNum::operator/(const int & b) const   //大数对一个整数进行相除运算
{
    BigNum ret;
    int i,down = 0;
    for(i = len - 1 ; i >= 0 ; i--)
    {
        ret.a[i] = (a[i] + down * (MAXN + 1)) / b;
        down = a[i] + down * (MAXN + 1) - ret.a[i] * b;
    }
    ret.len = len;
    while(ret.a[ret.len - 1] == 0 && ret.len > 1)
        ret.len--;
    return ret;
}
int BigNum::operator %(const int & b) const    //大数对一个int类型的变量进行取模运算
{
    int i,d=0;
    for (i = len-1; i>=0; i--)
    {
        d = ((d * (MAXN+1))% b + a[i])% b;
    }
    return d;
}
BigNum BigNum::operator^(const int & n) const    //大数的n次方运算
{
    BigNum t,ret(1);
    int i;
    if(n<0)
        exit(-1);
    if(n==0)
        return 1;
    if(n==1)
        return *this;
    int m=n;
    while(m>1)
    {
        t=*this;
        for( i=1;i<<1<=m;i<<=1)
        {
            t=t*t;
        }
        m-=i;
        ret=ret*t;
        if(m==1)
            ret=ret*(*this);
    }
    return ret;
}
bool BigNum::operator>(const BigNum & T) const   //大数和另一个大数的大小比较
{
    int ln;
    if(len > T.len)
        return true;
    else if(len == T.len)
    {
        ln = len - 1;
        while(ln >= 0&&a[ln] == T.a[ln])
            ln--;
        if(ln >= 0 && a[ln] > T.a[ln])
            return true;
        else
            return false;
    }
    else
        return false;
}
bool BigNum::operator >(const int & t) const    //大数和一个int类型的变量的大小比较
{
    BigNum b(t);
    return *this>b;
}

void BigNum::print()    //输出大数
{
    int i;
    printf("%d",a[len-1]);
    for(i = len - 2 ; i >= 0 ; i--)
    {
        printf("%04d",a[i]);
    }
    //cout << endl;
    printf("\n");
}
int bit[1000010] ;
char s[210] ;

void solve(int n,int ans)
{
    int j,i,v;
    i=0;j=n-1;
    while(i<j)
    {
        swap(bit[i],bit[j]) ;
        i++;j--;
    }
    bit[n]=0;
    for( i = 0 ; i < n ;i++)if(bit[i]&&bit[i+1])
    {
        j=i+2;
        while(j<n && bit[j])
        {
            j++ ;
        }
        v=j-i ;
        ans -= v-2;
        if(j != n)bit[j]=1;
        i=j-1;
    }
    cout << ans << endl;
}
int main()
{
    BigNum a ;
    int i,j,k,n,m;
    int len ,ans;
    while(scanf("%s",s) != EOF)
    {
        n = strlen(s) ;
        if(n==1&&s[0]==‘0‘) break ;
        a=BigNum(s) ;
       // a.print();
        len=ans=0;
        while(a>0)
        {
            if(a%2==1) bit[len++] =1,ans++;
            else bit[len++]=0;
            a = a/2;
        }
        printf("%d ",ans) ;
        solve(len,ans) ;
    }
    return 0 ;
}

时间: 2024-12-16 00:22:56

uvalive 6300 Signed Binary Representation of Integers的相关文章

[LeetCode] Prime Number of Set Bits in Binary Representation

Given two integers L and R, find the count of numbers in the range [L, R] (inclusive) having a prime number of set bits in their binary representation. (Recall that the number of set bits an integer has is the number of 1s present when written in bin

762. Prime Number of Set Bits in Binary Representation 二进制表示形式中的素数位数

Given two integers L and R, find the count of numbers in the range [L, R] (inclusive) having a prime number of set bits in their binary representation. (Recall that the number of set bits an integer has is the number of 1s present when written in bin

Lintcode: Binary Representation

Given a (decimal - e g 3.72) number that is passed in as a string,return the binary representation that is passed in as a string.If the number can not be represented accurately in binary, print “ERROR” Example n = 3.72, return ERROR n = 3.5, return 1

[Coding Made Simple] Number without consecutive 1s in binary representation

Given a number n, find the total number of numbers from 0 to 2^n - 1 which do not have consecutive 1s in their binary representation. Solution.  This problem is the equivalence of fibonacci sequence. For a given n, f(n) = f(n - 1) + f(n - 2). 1 publi

1. BinaryGap Find longest sequence of zeros in binary representation of an integer.

A binary gap within a positive integer N is any maximal sequence of consecutive zeros that is surrounded by ones at both ends in the binary representation of N. For example, number 9 has binary representation 1001 and contains a binary gap of length

Binary Representation

Given a (decimal - e.g. 3.72) number that is passed in as a string, return the binary representation that is passed in as a string. If the fractional part of the number can not be represented accurately in binary with at most 32 characters, return ER

[CareerCup] 5.2 Binary Representation of Real Number 实数的二进制表示

5.2 Given a real number between 0 and 1 (e.g., 0.72) that is passed in as a double, print the binary representation. If the number cannot be represented accurately in binary with at most 32 characters, print "ERROR."

Leetcode 762. Prime Number of Set Bits in Binary Representation

思路:动态规划.注意1024*1024>10^6,所以质素范围是(0,23). 1 class Solution { 2 public int countPrimeSetBits(int L, int R) { 3 Set<Integer> prime = new HashSet<Integer>(Arrays.asList(2,3,5,7,11,13,17,19,23)); 4 int[] count = new int[1+R]; 5 int res = 0; 6 for

Binary Numbers

描述 Given a positive integer n, find the positions of all 1's in its binary representation. The position of the least significant bit is 0. ExampleThe positions of 1's in the binary representation of 13 are 0, 2, 3. TaskWrite a program which for each