P1010 [NOIP 1998 普及组] 幂次方

题目描述

任何一个正整数都可以用 2 的幂次方表示。例如 137=27+23+20。

同时约定次方用括号来表示,即 ab 可表示为 a(b)。

由此可知,137 可表示为 2(7)+2(3)+2(0)

进一步:

7=22+2+20 ( 21 用 2 表示),并且 3=2+20。

所以最后 137 可表示为 2(2(2)+2+2(0))+2(2+2(0))+2(0)。

又如 1315=210+28+25+2+1

所以 1315 最后可表示为 2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)。

输入格式

一行一个正整数 n。

输出格式

符合约定的 n 的 0,2 表示(在表示中不能有空格)。

思路:

1、数据量很小,看明白做法了打表就行

2、分治递归

 这道题主要是将所有的数都分为0——2(0)和1——2这两种数,所以不论是原来的整数还是化为指数的情况下,都要继续递归直至0和1。

就比如137——128(2^7)+8(2^3)+1(2^0),这道题既然要做递归,那么就要有特判,否则就会让结果乱套了。

打表:


import java.util.Scanner;

public class Main {
	static Scanner sc = new Scanner(System.in);
	static int[] r = new int[20];
	static String[] num = new String[]
	{"2(0)","2","2(2)",	//0 1 2
	 "2(2+2(0))","2(2(2))",	//3 4
	 "2(2(2)+2(0))","2(2(2)+2)",	//5 6
	 "2(2(2)+2+2(0))","2(2(2+2(0)))",	//7 8
	 "2(2(2(2))+2(0))","2(2(2+2(0))+2)",	//9 10
	 "2(2(2(2))+2+2(0))","2(2(2(2))+2(2))",		//11 12
	 "2(2(2(2))+2(2)+2(0))","2(2(2+2(0))+2(2)+2)", //13 14
	 "2(2(2(2))+2(2)+2+2(0))"	//15
	};
	public static void main(String[] args) {
		int n = sc.nextInt();
		for (int i = 0; n != 0; i++) {
			if(n % 2 == 1)r[i] = 1;
			n /= 2;
		}
		int flag = 1;
		for (int i = 15; i >= 0; i--) {
			if(r[i] == 1) {	//有1输出对应串
				System.out.printf("%s%s",flag==1?"":"+",num[i]);
				flag = 0;
			}
			
		}
	}
}

递归:

 

import java.util.Scanner;
public class Main {
	static Scanner sc = new Scanner(System.in);
	static int[] r = new int[20];
	public static void main(String[] args) {
		r[0] = 1;
		int n = sc.nextInt();
		for (int i = 1; i <= 17; i++)r[i] = r[i-1]*2;
		f(n);
	}
	static void f(int n) {
		int flag = 0;
		while(r[flag] <= n)flag++;
		flag--;
		if(flag == 0) {
			System.out.print("2(0)");
		}else if(flag == 1) {
			System.out.print("2");
		}else {
			System.out.print("2(");
			f(flag);	//对其指数进行拆分
			System.out.print(")");
		}//先将大数拆分为几个数,每个数再对自己的数进行拆分,每个数都拆分成2和2(0)
		n -= r[flag];
		if(n != 0) {//判断原数是否还有剩余,有就连接
			System.out.print("+");
			f(n);	//还能继续拆解
		}
	}
}

你可能感兴趣的:(算法,java)