HDU1032 - The 3n + 1 problem (暴力)
2015-09-03 16:45
274 查看
题目链接
思路
代码
暴力打表
优化暴力
线段树超时
需要注意的是输出格式,输入的 aa 可能 >b>b,直接交换的话,输出时,要换过来。直接打表这样的效率比较低,已经过了半秒了。
ACAC后脑洞大开,想用线段树来提高查询效率,电脑没电,明天继续。
很不幸,超时了,应该是后台数据的问题,给的查询数据很少。所以我们并不需要直接将所有的数据算出来,而是根据读入来计算,0ms AC0ms~AC。
思路
代码
暴力打表
优化暴力
线段树超时
思路
直接 暴力 就行,先算出所有的结果,然后读入数据后遍历区间找到最大值即可。需要注意的是输出格式,输入的 aa 可能 >b>b,直接交换的话,输出时,要换过来。直接打表这样的效率比较低,已经过了半秒了。
ACAC后脑洞大开,想用线段树来提高查询效率,电脑没电,明天继续。
很不幸,超时了,应该是后台数据的问题,给的查询数据很少。所以我们并不需要直接将所有的数据算出来,而是根据读入来计算,0ms AC0ms~AC。
代码
暴力打表
#include <cstdio> #include <cstdlib> #include <algorithm> using namespace std; int ans[1000100]; int a, b; void init() { int count; long long num; for(int i=1; i<=1000000; i++) { count = 1, num = i; while(num!=1) { if(num&1) num = num * 3 + 1; else num /= 2; count++; } ans[i] = count; } } int main() { init(); while(scanf("%d%d", &a, &b)==2) { int re = 0; printf("%d %d ", a, b); if(a>b) swap(a, b); for(int i=a; i<=b; i++) re = max(re, ans[i]); printf("%d\n", re); } return 0; }
优化暴力
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; int ans[1000100]; int a, b; int main() { memset(ans, -1, sizeof(ans)); while(scanf("%d%d", &a, &b)==2) { int re = 0; printf("%d %d ", a, b); if(a>b) swap(a, b); for(int i=a; i<=b; i++) { if(ans[i]==-1) { int count = 1, num = i; while(num!=1) { if(num&1) num = num * 3 + 1; else num /= 2; count++; } ans[i] = count; } re = max(re, ans[i]); } printf("%d\n", re); } return 0; }
线段树超时
#include <cstdio> #include <cstdlib> #include <algorithm> #define lson tree[root].ls #define rson tree[root].rs using namespace std; const int maxn = 1000000; int a, b; struct node { int l, r; int ls, rs; int ans; }tree[maxn*2+10]; int nCount = 1; int ans[1000100]; void init() { int count; long long num; for(int i=1; i<=1000000; i++) { count = 1, num = i; while(num!=1) { if(num&1) num = num * 3 + 1; else num /= 2; count++; } ans[i] = count; } } void build(int root, int l, int r) { tree[root].l = l; tree[root].r = r; if(l==r) { tree[root].ans = ans[l]; // 至今想不懂,在本机测试时,同样的代码,这样直接算耗时太多了 // int count = 1, num = l; // while(num!=1) // { // if(num&1) num = num * 3 + 1; // else num /= 2; // count++; // } // tree[root].ans = count; } else { int mid = (l+r)/2; lson = ++nCount; build(lson, l, mid); rson = ++nCount; build(rson, mid+1, r); tree[root].ans = max(tree[lson].ans, tree[rson].ans); } } void query(int root, int l, int r, int & ans) { if(tree[root].l==l && tree[root].r==r) { ans = max(ans, tree[root].ans); } else { int mid = (tree[root].l+tree[root].r)/2; if(r<=mid) query(lson, l, r, ans); else if(l>=(mid+1)) query(rson, l, r, ans); else { query(lson, l, mid, ans); query(rson, mid+1, r, ans); } } } int main() { init(); build(1, 1, maxn); while(scanf("%d%d", &a, &b)==2) { int re = 0; printf("%d %d ", a, b); if(a>b) swap(a, b); query(1, a, b, re); printf("%d\n", re); } return 0; }
相关文章推荐
- tar 压缩与解压命令(汇总)
- VMware配置桥接方式(Bridged)
- TCP&UDP部分细节
- Regionals 2014 >> Latin America >> 6828 - Help cupid
- POJ 2987 Firing(最大权闭合)
- net extjs tree异步加载数据
- Ubuntu中安装mongodb的问题
- Spring mvc的相关问题
- poj 1195 Mobile phones (二维树状数组)
- JDK5至JDK8的新特性
- 哈希
- 电话本管理系统(使用数组)
- 滑动窗口_单调队列入门 (白书P241)
- 二分查找
- Matlab界面设计入门
- for 语句头中多个定义
- 替换空格
- 数据结构 1____概论
- PAT(B) 1021. 个位数统计(简单哈希)
- 使用极光推送自定义消息打造个性的消息推送效果