【剑指offer之求1+2+...+n】九度OJ-1506-求1+2+3+...+n
来源:互联网 发布:中囯邮政网络培训学院 编辑:程序博客网 时间:2024/05/20 23:38
【题目链接】:九度OJ-1506-求1+2+3+…+n
【题目描述】:
题目 1506:求1+2+3+…+n
时间限制:1 秒内存限制:128 兆特殊判题:否提交:1857解决:1060
题目描述:
求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
输入:
输入可能包含多个测试样例。
对于每个测试案例,输入为一个整数n(1<= n<=100000)。
输出:
对应每个测试案例,
输出1+2+3+…+n的值。
样例输入:
3
5
样例输出:
6
15
【思路】这道题很考察发散思维,具体参见如下:
这里给出四钟解法,如果还有其他的欢迎大家补充~
【解法一】利用构造函数求解
我们仍然围绕循环做文章,循环只是让相同的代码重复执行n遍而言,我们完全可以不用for和while来达到这个效果,比如我们先定义一个类型,接着创建n个该类型的实例,那么这个类型的构造函数将确定会被调用n 次。我们可以将与累加相关的代码放到构造函数中,代码如下:
// ====================方法一===================class temp{public: temp() { ++n; sum += n; } static void reset() {n=0; sum=0;} static unsigned int GetSum() {return sum;}private: static unsigned int n; static unsigned int sum;};unsigned int temp::n = 0;unsigned int temp::sum = 0;unsigned int sum_solution1(unsigned int n){ temp::reset(); temp *a = new temp[n]; delete []a; a = NULL; return temp::GetSum();}
【解法二】利用虚函数求解
我们同样也可以围绕递归做文章。既然不能在一个函数中判断是不是应该终止递归,那么我们不妨定义两个函数:一个函数充当递归函数的角色,另一个函数处理递归的情况,我们需要做的就是在两个函数里二选一。从二选一我们很自然地想到布尔变量,比如值为true{1}的时候调用第一个函数,值为false的时候调用第二个函数,那现在的问题是如何把数值变量n换成布尔值,如果对n连续做两次反运算,即!!n那么非零的n转换为true,0转换为false。有了上述分析,我们再来看下面的代码:
// ====================方法二===================class A;A* array[2];class A{public: virtual unsigned int sum(unsigned int n) { return 0; }};class B: public A{public: virtual unsigned int sum(unsigned int n) { return array[!!n]->sum(n-1)+n; }};int sum_solution2(int n){ A a; B b; array[0]= &a; array[1]= &b; int value = array[1]->sum(n); return value;}
这种思路是用虚函数来实现的选择。当n!=0时调用函数B::sum;否则调用函数A::sum。
【解法三】利用函数指针求解
在纯C语言的编程环境中,我们不能使用函数,此时可以用函数指针来模拟,这样代码可能还更加直观:
// ====================方法三===================typedef unsigned int (*fun)(unsigned int);unsigned int solution3_temp(unsigned int n){ return 0;}unsigned int sum_solution3(unsigned int n){ static fun f[2] = {solution3_temp,sum_solution3}; return n + f[!!n](n-1);}
【解法四】利用模板类型求解
另外我们还可以让编译器帮助完成类似递归的计算代码如下:
// ====================方法四===================template <unsigned int n> struct sum_solution4{ enum value{N = sum_solution4<n-1>::N+n};};template <> struct sum_solution4<1>{ enum value { N = 1};};template <> struct sum_solution4<0>{ enum value { N = 0};};
【说明】:强调内容 sum_solution4<100>::N 就是求1+2+…+100的结果,当编译器看到sum_soution4<100>时,就会为模板类sum_solution4 以参数100生成该类型的代码。但以100为参数的类型需要得到以99为参数的类型,因为sum_solution4<100>::N=sum_solution4<99>::N+100.这个过程会一直到参数为1的类型,由于该类型已经显示定义,编译器无须生成,递归编译到此结束。由于这个过程是在编译过程中完成的,因此要求输入n必须是在编译期间就能确定的常量,不能动态输入,这是该方法最大 确定,而且编译器对递归编译代码的递归深度有限制的,也就是要求n不能太大。
完整测试代码:
/********************************** Date:2017-04-15 21:40* Author:herongwei* Problem: 题目1506:求1+2+3+...+n* Source:http://ac.jobdu.com/problem.php?pid=1506 【剑指Offer 】* Result:AC**********************************/#pragma comment(linker,"/STACK:102400000,102400000")#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <set>#include <stack>#include <math.h>#include <map>#include <queue>#include <deque>#include <vector>#include <algorithm>using namespace std;typedef long long LL;const int maxn = 1e5+10;const int maxm = 55;const LL MOD = 999999997;int dir4[4][2]= {{1,0},{0,1},{-1,0},{0,-1}};int dir8[8][2]= {{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};inline int read(){ int c=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();} return c*f;}// ====================方法一===================class temp{public: temp() { ++n; sum += n; } static void reset() {n=0; sum=0;} static unsigned int GetSum() {return sum;}private: static unsigned int n; static unsigned int sum;};unsigned int temp::n = 0;unsigned int temp::sum = 0;unsigned int sum_solution1(unsigned int n){ temp::reset(); temp *a = new temp[n]; delete []a; a = NULL; return temp::GetSum();}// ====================方法二===================class A;A* array[2];class A{public: virtual unsigned int sum(unsigned int n) { return 0; }};class B: public A{public: virtual unsigned int sum(unsigned int n) { return array[!!n]->sum(n-1)+n; }};int sum_solution2(int n){ A a; B b; array[0]= &a; array[1]= &b; int value = array[1]->sum(n); return value;}// ====================方法三===================typedef unsigned int (*fun)(unsigned int);unsigned int solution3_temp(unsigned int n){ return 0;}unsigned int sum_solution3(unsigned int n){ static fun f[2] = {solution3_temp,sum_solution3}; return n + f[!!n](n-1);}// ====================方法四===================template <unsigned int n> struct sum_solution4{ enum value{N = sum_solution4<n-1>::N+n};};template <> struct sum_solution4<1>{ enum value { N = 1};};template <> struct sum_solution4<0>{ enum value { N = 0};};// ====================测试代码===================void Test(int n,int expected){ printf("Test for %d begin:\n",n); if(sum_solution1(n) == expected) printf("solution1 passed.\n"); else printf("solution1 failed.\n"); if(sum_solution2(n) == expected) printf("solution2 passed.\n"); else printf("solution2 failed.\n"); if(sum_solution3(n) == expected) printf("solution3 passed.\n"); else printf("solution3 failed.\n");}void Test1(){ const unsigned int number = 1; int expected = 1; Test(number, expected); if(sum_solution4<number>::N == expected) printf("solution4 passed.\n"); else printf("solution4 failed.\n");}void Test2(){ const unsigned int number = 5; int expected = 15; Test(number, expected); if(sum_solution4<number>::N == expected) printf("solution4 passed.\n"); else printf("solution4 failed.\n");}void Test3(){ const unsigned int number = 10; int expected = 55; Test(number, expected); if(sum_solution4<number>::N == expected) printf("solution4 passed.\n"); else printf("solution4 failed.\n");}void Test4(){ const unsigned int number = 0; int expected = 0; Test(number, expected); if(sum_solution4<number>::N == expected) printf("solution4 passed.\n"); else printf("solution4 failed.\n");}int main(){ //freopen("in.txt","r",stdin); Test1(); Test2(); Test3(); Test4(); return 0;}/* /////////////solution/////////////////Test for 1 begin:solution1 passed.solution2 passed.solution3 passed.solution4 passed.Test for 5 begin:solution1 passed.solution2 passed.solution3 passed.solution4 passed.Test for 10 begin:solution1 passed.solution2 passed.solution3 passed.solution4 passed.Test for 0 begin:solution1 passed.solution2 passed.solution3 passed.solution4 passed./////////////solution////////////////*/
- 【剑指offer之求1+2+...+n】九度OJ-1506-求1+2+3+...+n
- 【剑指Offer面试编程题】题目1506:求1+2+3+...+n--九度OJ
- 九度OJ-题目1506:求1+2+3+...+n
- 《剑指offer》求1+2+3+...+n
- 剑指offer--求1+2+3+...+n
- 剑指offer-求1+2+3+...+n
- 剑指offer:求1+2+3+...+n
- 《剑指offer》-求1+2+3+...+n
- 剑指Offer: 求1+2+3+...+n
- 【剑指Offer】求1+2+3+...+n
- 剑指offer---求1+2+3+...+n
- 剑指offer 求1+2+3+...+n
- 剑指offer:求1+2+3+...+n
- 剑指Offer-求1+2+3+...+n
- 剑指offer-求1+2+3+...+n
- 求1+2+3+...+n 剑指offer
- 剑指offer:求1+2+3+...+n
- 求1+2+3+...+n(剑指Offer)
- Python装饰器
- codevs 1281 Xn数列 快速幂+快速加防溢出
- ZOJ
- Swift 字典 Dictionary基本用法
- 4.dialog 工具
- 【剑指offer之求1+2+...+n】九度OJ-1506-求1+2+3+...+n
- 笔试
- hdu1176免费馅饼 dp
- List Map Set的比较
- Vue学习心得(1)vue的安装
- 调试经验-ORA-12560: TNS: 协议适配器错误
- python自动执行脚本
- java--构造函数
- ZOJ