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%。代码如下:

 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     }
View Code

法二(借鉴):一层for循环,o(n)。利用双指针的思想,一个指针从2开始,每次都乘以2,另一个指针从n/2开始,每次都除以2,两者同时遍历,一旦另一个指针成为奇数,则说明找到结果,因为前一个指针一定是偶数,且是最小偶数的情况。代码如下:

 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     }
View Code
原文地址:https://www.cnblogs.com/cing/p/8777942.html