sicily 1214
来源:互联网 发布:java同时定义多个变量 编辑:程序博客网 时间:2024/06/06 00:47
题目链接:sicily 1214
解题思路:
首先我觉得这是一道很好而且比较难的题,难度在于找规律。
题目告诉我们,n是一个很大的数(刚好在unsigned的范围内),这样的话,直接模拟是必然超时的,所以,我们需要根据题目的三条公式来推导a[n]。
这个规律我找了很久也没能找到,最后直接拿来用的,怎么想得到的我也不懂。规律如下:如果n的二进制形式满足回文序列的形式,那么a[n]=n。
得到这个规律,那么我们的题目就可以转换成找[1,n]中找到所有的数i,i满足二进制形式是回文序列。前面已经排除掉暴力模拟这个解法了,那么我们现在就只能构造了。考虑到i的二进制顶多也就是32位,回文序列的话我们可以只看16位,所以我们可以暴力枚举前16位,然后再用翻转操作求得整个回文序列,这样时间复杂度是2^16,可以接受。
之后的事情就是深搜暴力枚举啦,不再废话!
代码:
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;unsigned n,tmp;unsigned cnt,ans;const unsigned delta=1;unsigned getLen(unsigned num){ unsigned len=0; while(num) num>>=1,len++; return len;}unsigned reverse(unsigned num){ unsigned res=0; while(num) { res=(res<<1)|(num&1); num>>=1; } return res;}void cal(unsigned num){ if(num==0) return; unsigned len=getLen(num),res=0; if(((num<<len)|reverse(num))<=n) ans++; if(((num<<len-1)|reverse(num>>1))<=n) ans++;}void dfs(unsigned sum,int cnt){ if(cnt==0) { cal(sum); return; } dfs(sum<<1,cnt-1); dfs((sum<<1)+delta,cnt-1);}int main(){ while(~scanf("%u",&n)) { ans=0; dfs(0,16); printf("%u\n",ans); } return 0;}
总结:
1、用二进制的思想考虑算法
2、多使用位运算
0 0
- sicily 1214
- sicily 1214 信号分析
- sicily 1214 二进制回文数的证明
- Sicily 1027
- sicily 1007
- sicily 1795
- sicily 1036
- sicily 1419
- sicily 1889
- sicily 1684
- sicily 1686
- sicily 1004
- sicily 1135
- sicily 1152
- sicily 1151
- sicily 1002
- sicily 1156
- sicily 1424
- pip通过公司防火墙
- Spring 之注解事务@Transactional
- php面向对象编程-类与对象
- Grunt与WebStrom集成
- hdu 1381
- sicily 1214
- Maven实战——Maven的坐标和依赖
- Android图片上传
- 黑马程序员----IO流(一)
- STL源码解析-01stl配置文件
- 黑马程序员—C重点--结构体
- mongodb数据库的备份与恢复
- HDU 2544
- SQL Server 2012 SQLEXPRESS 127.0.0.1(IP地址方式)无法连接访问问题的解决