USACO - 2.1.2 - Ordered Fractions

 

原创文章转载请注明出处


摘要: 模拟 ,互质

一. 题目翻译

1. 描述:
          输入一个自然数N,对于一个最简分数a/b(分子和分母互质的分数),满足1<=b<=N,0<=a/b<=1,请找出所有满足条件的分数。
这有一个例子,当N=5时,所有解为:0/1 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 1/1
给定一个自然数N,1<=n<=160,请编程按分数值递增的顺序输出所有解。
注:①0和任意自然数的最大公约数就是那个自然数②互质指最大公约数等于1的两个自然数。

2. 格式:

          INPUT FORMAT:

          (file frac1.in)
          单独的一行 一个自然数N(1..160)

          OUTPUT FORMAT:

          (file frac1.out)
          每个分数单独占一行,按照大小次序排列

3. SAMPLE:
          SAMPLE INPUT:
5
          SAMPLE OUTPUT:
0/1
1/5
1/4
1/3
2/5
1/2
3/5
2/3
3/4
4/5
1/1
          
二.  题解

1. 题意理解(将问题分析清楚,大致用什么思路):
          这道题目我用了非常笨的办法,枚举分子(>1)和分母(>1),分为以下几种情况讨论:
          a. 分母为质数,则分子分母必然互质,加入结果集
          b. 分母为合数,若分子为质数,则判断分母是否为分子的倍数,如果不是分子的倍数,则加入结果集
          c. 分母为合数,若分子也为合数,则判断二者是否存在公约数,如果没有公约数则加入结果集
          最后对结果集排序,输出结果集结果。

 

2.  具体实现(具体实现过程中出现的问题):
          按照上述算法描述编写程序。

3. 需要注意的细节:

          1. 排序的实现,我们使用了java中自带的Arrays.sort()方法, 这个方法的时间复杂度为nlogn,同时注意Comparable接口的实现。 
          2. 计算素数的上限我们使用了Math.sqrt(p),这个需要积累,可以大大降低时间复杂度。

4. 启示:

其实这道题完全可以更简单,当做水题来做。维护一个Hash表,将枚举产生分数入Hash表就可以了,判重的问题由Hash表来做就可以了,避免自己判断的三种情况讨论。

三.  代码

/* ID:fightin1 LANG:JAVA TASK:frac1 */ import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Scanner; public class frac1 { public static void main(String[] args) { try { // Scanner in = new Scanner(System.in); // PrintWriter pw = new PrintWriter(System.out); Scanner in = new Scanner(new BufferedReader(new FileReader( "frac1.in"))); PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter( "frac1.out"))); int num = in.nextInt(); ArrayList<Node> al = new ArrayList<Node>(); al.add(new Node(0,1)); al.add(new Node(1,1)); for(int i=2;i<=num;i++){ al.add(new Node(1,i)); for (int j=2;j<i;j++){ if (isP(i)){ al.add(new Node(j,i)); } else { if (isP(j)){ if (i%j!=0){ al.add(new Node(j,i)); } } else { boolean add = true; for (int k=2;k<=j/2;k++){ if (j%k==0&&i%k ==0){ add = false; break; } } if (add){ al.add(new Node(j,i)); } } } } } Object[] results = al.toArray(); Arrays.sort(results); for (int i=0;i<results.length;i++){ pw.println(((Node)results[i]).fenzi+"/"+((Node)results[i]).fenmu); } pw.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static boolean isP(int a){ boolean p = true; for (int i=2;i<=Math.sqrt(a);i++){ if (a%i == 0){ p = false; break; } } return p; } } class Node implements Comparable<Node>{ int fenzi; int fenmu; float value; public Node(int fenzi ,int fenmu) { this.fenzi = fenzi; this.fenmu = fenmu; value = (float)fenzi/(float)fenmu; } @Override public int compareTo(Node o) { if (this.value > o.value){ return 1; } else if (this.value == o.value){ return 0; } else { return -1; } } } 



 

 

 

 

你可能感兴趣的:(action)