UVa系列——100/The 3n + 1 problem

原创 2012年03月30日 22:59:44

引用请注明出处:http://blog.csdn.net/int64ago/article/details/7413434

本题注意两个方面:

1、虽然题目给的范围是1~1000000,其实计算的过程中的中间值有的是很大的,所以要用unsigned long long

2、不重复计算,我同时用了两种方案,一种是计算的过程中判断是否遇到已经计算过的,另一种是计算的过程中把“有意义”的中间值存了起来,然后得到结果的时候顺便回溯处理了,事实证明两种一起用效率还不错,44ms过了


#include  <stdio.h>
#include  <stdlib.h>
#define  MAX_NUM 1000000

int cyc_num[MAX_NUM + 1]={0};
int back_cyc_num[MAX_NUM+1];
int back_len;


/* 处理连带计算出来的cyc_num[] */
void pro_back(int ret_num)
{
	int i;
	for(i = 0; i != back_len; ++i){
		cyc_num[back_cyc_num[i]] = ret_num + back_len - i;
	}
	
}


/*
 * 计算cyc_num[num]的值
 * 如果计算过程中遇到已经计算过得cyc_num[]
 * 则不重复计算
 */
int do_creat_cyc(unsigned long long num)
{
	int cnt = 1;
	back_len = 0;
	while(num != 1){
		if(num % 2 == 0){
			num /= 2;
		} else{
			num = num * 3 + 1;
		}
		if(num <= MAX_NUM && cyc_num[num]){
			pro_back(cyc_num[num]);
			return cnt + cyc_num[num];
		}
		back_cyc_num[back_len++] = num > MAX_NUM ? 0:num;	
		++cnt;
	}
	return cnt;
}


/* 
 * 计算1~1000000之间所有的cyc_num[]值
 * 如果已经计算过则跳过
 */
void creat_cyc(void)
{
	int i;
	for(i = 1; i <= MAX_NUM; ++i){
		if(cyc_num[i]){
			continue;
		} else{
			cyc_num[i] = do_creat_cyc(i);
		}
	}
	
}


void let_small_big(int *const x, int *const y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}

int get_max(int beg, int end)
{
	int mmax = 0;
	int i;
	if(beg > end){
		let_small_big(&beg, &end);
	}
	for(i = beg; i <= end; ++i){
		if(mmax < cyc_num[i]){
			mmax = cyc_num[i];
		}
	}
	return mmax;	
}



int main(int argc, char *argv[])
{
	int beg, end;
	creat_cyc();
	while(scanf("%d%d", &beg, &end) != EOF){
		printf("%d %d %d\n", beg, end, get_max(beg, end));
	}
	return 0;
}

3n+1_problem_Uva

这道题,其实说难也难,说简单也简单,关键在其测试数据。如果测试数据很苛刻,就很难了(参看博客UVa Problem 100 The 3n+1 problem (3n+1 问题))。 这里,我要写两点想...
  • cylj102908
  • cylj102908
  • 2016年04月30日 22:49
  • 262

HDOJ, 杭电1032, The 3n+1 problem. POJ, 北大OJ,1207....数学题。。又一发

一个英文题。。。 Uva的第一道题目。HDOJ的1032题,POJ的1207题、、、 坑爹的POJ居然不识别 _int64,不过还好,他没要求大于int型的数字。。。所以,用int,AC险过了。。。 ...
  • hu1020935219
  • hu1020935219
  • 2013年09月21日 13:58
  • 1455

3n+1problem

B - The 3n + 1 problem Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit...
  • a716121
  • a716121
  • 2015年08月19日 17:32
  • 646

UVa - 100 The 3n + 1 problem

The 3n + 1 problem UVa - 100 POJ - 1207 SDUSTOJ - 1049
  • JinxiSui
  • JinxiSui
  • 2017年12月17日 16:52
  • 66

UVA 100 - The 3n + 1 problem

题目链接:点击打开链接 题目大意:给你两个数字,在这两个数字之间,如果一个数字是偶数,就让他除以2,如果是奇数,就让他乘以3再加一,直到这个数变成一。记录次数,输出最多的次数 一道水题~但是有个坑...
  • qq_37943488
  • qq_37943488
  • 2017年08月29日 17:54
  • 82

UVa 100 - The 3n + 1 problem

下午,开完见面会就回来做了,不知道做哪里的题
  • wcr1996
  • wcr1996
  • 2014年10月13日 21:48
  • 1259

uva 100 The 3n + 1 problem

简单题目,不多说了,纯当练习,注意输入的两个数的大小关系式不确定的。 #include int get_loop_len(int n) { int count; count = 1; ...
  • xiaohaowudi
  • xiaohaowudi
  • 2013年09月16日 10:27
  • 517

UVa 100 The 3n + 1 problem

UVa 100 The 3n + 1 problem #include #include #include using namespace std; int solve(int i, int cn...
  • u012041274
  • u012041274
  • 2013年09月09日 21:28
  • 259

The 3n + 1 problem UVA - 100

问题描述:极简主义代码。 问题链接 03pie’s solution for [UVA-100]: #include using namespace std;int clen(int n){...
  • qq_34677945
  • qq_34677945
  • 2017年05月23日 22:45
  • 98

UVa - 100 - The 3n + 1 problem

其实注意输入的时候的陷阱就行了,第一题水题。。。把第一题翻出来做做也是很不错的。...
  • zyq522376829
  • zyq522376829
  • 2015年07月02日 14:20
  • 387
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:UVa系列——100/The 3n + 1 problem
举报原因:
原因补充:

(最多只允许输入30个字)