找到两个给定数字之间的数字总数的最佳方法是什么,其二进制表示是回文? The problem I am trying to solve is here on spoj http://www.spoj.com/problems/BINPALI/
答案 0 :(得分:1)
一种可能的方法是:
取第一个数字M的二进制表示。
以二进制表示法找出第一个大于M的回文数:
- 对于M,保持左半部分的位,相同的值,并将二进制字符串的右半部分与左半部分匹配。
For example if M is 10110111, the number shall be 10111101
如果结果数是< M,然后将左子串增加1,然后匹配右子串。
Eg. if M is 10000011, the number shall be 10000001 < M , hence number shall be 10011001.
要查找后续数字,请从中间向末尾增加位数。
10011001
10100101
10111101
11000011
答案 1 :(得分:1)
我解决了spoj问题和代码如下:
#include<iostream>
#include<algorithm>
#include<cctype>
#include<cstring>
#include<string>
using namespace std;
int main()
{
int a,b,t;
cin>>t;
while(t--)
{
cin>>a>>b;
int total=0;
string s="";
while(a<=b)
{
s="";
for(int i=a;i>0;i=i/2)
{
if(i%2)
s+='1';
else
s+='0';
}
string s2="",s3="";
s2=s.substr(0,s.length()/2);
int k=s.length();
if(k%2)
s3=s.substr(s.length()/2+1,s.length());
else
s3=s.substr(s.length()/2,s.length());
reverse(s2.begin(),s2.end());
if(s2==s3)
{
cout<<a<<" ";
total++;
}
a++;
}
if(!total)
cout<<"none"<<endl;
}
return 0;
}
答案 2 :(得分:0)
此问题的时间限制非常严格。即使是优化的回文生成器也可能不起作用。您可能必须对此给定的整数序列使用formula at OEIS。
还有一个反演公式。它给出如下。
反演公式:如果b> 0是任何二元回文,那么a(n)= b的索引n是 n = palindromicIndexOf(b)=(((5 - ( - 1)^ m)/ 2)+ sum_ {k = 1 ... floor(m / 2)}(floor(b / 2 ^ k)mod 2) / 2 ^ k))* 2 ^ floor(m / 2),其中m = floor(log_2(b))。
您可能必须采用两个给定的索引,并以某种方式从序列中找到最低的n和最高的n。然后打印出范围内的序列中的所有第n个数字(最低n,最高n)。对于第n个二元回文数的每个查询是O(1)时间,因此每个测试用例应该采用O(log(B-A))时间。这非常低,但你需要让配方工作。 :)
祝你为这个序列实现生成器公式。我试过了,无法让它发挥作用。 :(这很复杂。
但无论如何参考,我尝试在Python 2.7.5中使用优化的回文生成器,它给了我超时限制。如果您有兴趣,这是代码。
from itertools import product, repeat
from bisect import insort, bisect
def all_binary_sequences_of_length_(n):
return [''.join(seq) for seq in product('01', repeat=n)]
def main():
binary_palindromes = [0, 1, 3, 5, 7]
for n in xrange(1, 15):
A = all_binary_sequences_of_length_(n)
for a in A:
b = a[::-1]
# Add palindromes of length 2n + 2
insort(binary_palindromes, int((a+b).join('11'), 2))
# Add palindromes of length 2n + 3
insort(binary_palindromes, int((a+'0'+b).join('11'), 2))
insort(binary_palindromes, int((a+'1'+b).join('11'), 2))
t = int(raw_input())
for _ in repeat(0, t):
a, b = map(int, raw_input().split())
start = bisect(binary_palindromes, a - 1)
end = bisect(binary_palindromes, b)
output = [str(binary_palindromes[i]) for i in xrange(start, end)]
if len(output) == 0:
print 'none'
else:
print ' '.join(output)
if __name__ == '__main__':
main()
我意识到Python不是一种非常快速的语言,但只有1秒的时间限制让我相信解决这个问题的唯一方法是使用OEIS中的公式。 :)
答案 3 :(得分:0)
Python功能强大!不要让它变得复杂!好吧,它有点慢!
for _ in range(input()):
has = False
x,y = map(int, raw_input().split())
for i in range(x,y+1):
temp = bin(i)
temp = temp[temp.index('b')+1:]
if temp[::-1] == temp:
has = True
print i,
if not has:
print "none"