2018京东---分解整数
题目大意:给出一个数,将其分解成一个偶数和一个奇数的乘积。如果不能分解,则输出No。
输入:
t(下面有t行数据)
n(范围是2~2^63)
例子:
2
10
5
输出:
对于每个数据,输出其偶数和奇数(如果有多组,输出偶数最小的那组,输出格式:奇数 偶数),否则输出No。
例子:
5 2
No
法一:两层for循环,o(n^2)。外层循环是偶数,从2开始,内层循环是奇数,从1开始,每次自增2,一旦找到偶数*奇数=n,则退出循环,输出结果。因为要是偶数最小的,所以,一旦找到就是最后结果。tips:一个偶数*一个奇数=偶数。所以如果输入是奇数,可以直接判定为No。超时了。过了40%。代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public static void main(String[] args) throws IOException { 2 BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 3 String line = in.readLine(); 4 int t = Integer.parseInt(line); 5 while(t-- != 0) { 6 line = in.readLine(); 7 long n = Long.parseLong(line); 8 //如果输入是奇数,直接判定不能分解 9 if(n % 2 != 0) { 10 System.out.println("No"); 11 continue; 12 } 13 //如果输入是偶数 14 else { 15 long ji = n, ou = n; 16 boolean flag = false; 17 //i代表偶数 18 for(long i = 2; i <= n; i += 2) { 19 //j代表奇数 20 for(long j = 1; j <= n; j += 2) { 21 //一旦找到则是结果 22 if(i * j == n) { 23 ou = i; 24 ji = j; 25 flag = true; 26 break; 27 } 28 } 29 if(flag == true) { 30 break; 31 } 32 } 33 System.out.println(ji + " " + ou); 34 } 35 } 36 }
法二(借鉴):一层for循环,o(n)。利用双指针的思想,一个指针从2开始,每次都乘以2,另一个指针从n/2开始,每次都除以2,两者同时遍历,一旦另一个指针成为奇数,则说明找到结果,因为前一个指针一定是偶数,且是最小偶数的情况。代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public static void main(String[] args) throws IOException { 2 BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 3 String line = in.readLine(); 4 int t = Integer.parseInt(line); 5 while(t-- != 0) { 6 line = in.readLine(); 7 long n = Long.parseLong(line); 8 //如果输入是奇数,直接判定不能分解 9 if(n % 2 != 0) { 10 System.out.println("No"); 11 continue; 12 } 13 //如果输入是偶数 14 else { 15 //初始化奇数和偶数,从最开始,两者乘积就是n,为后面遍历打基础 16 long ou = 2, ji = n / 2; 17 //有种双指针的味道,只是这里不是加减,而是乘除 18 //由于初始化的时候,两者乘积就是n,而且这里两者乘除的数也是一样的,所以每一次的操作,都保证了,两者的乘积是n,所以一旦找到一个奇数,则说明就是结果。因为ou始终是偶数。 19 while(ji % 2 == 0) { 20 ou *= 2; 21 ji /= 2; 22 } 23 System.out.println(ji + " " + ou); 24 } 25 } 26 }