HDU 1016(Java) 好大一个坑!!!
2016-03-02 19:09
441 查看
Prime Ring Problem
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 38463 Accepted Submission(s): 17008
Problem Description
A ring is compose of n circles as shown in diagram. Put
natural number 1, 2, …, n into each circle separately, and the sum of numbers in
two adjacent circles should be a prime.
Note: the number of first circle should always be 1.
Input
n (0 < n < 20).
Output
The output format is shown as sample below. Each row represents a series of circle
numbers in the ring beginning from 1 clockwisely and anticlockwisely.
The order of numbers must satisfy the above requirements. Print solutions in
lexicographical order.
You are to write a program that completes above process.
Print a blank line after each case.
Sample Input
6
8
Sample Output
Case 1:
1 4 3 2 5 6
1 6 5 2 3 4
Case 2:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2
深搜的一道水题,原先用C++AC了,因为要学习Java,就用Java撸了一遍。然而悲剧就这么发生了,同样的逻辑代码,符号题目要求的输出,提交了一整天总是presentation error,万般无奈之下去网上搜AC代码,然而没有Java版的,所以只好对着C语言一个个看,后来一步一步调试,才发现要在Case %d:后面再加个空格(可是题目描述和C++版中都没有这个空格)。~~~~,虽然Java运行慢,用Java打比赛的人少,但也不能这么坑人吧!
note:
1.数据规模小,所以把1~37的所有素数都找到了,打表空间换时间。
2.数据优化:再考虑输入的特点,如果输入N是奇数的话,由于起点从1开始,那么1-N之间一共有N / 2个偶数,N / 2 + 1个奇数,也就是奇数的个数比偶数多一个,那么把这N个数排成一个环,根据鸽巢原理,必然有两个奇数是相邻的,而两个奇数之和是偶数,偶数不是素数,所以我们得出结论,如果输入N是奇数的话,没有满足条件的排列。这样当N是奇数的时候,直接返回即可。如果1-N之间每个数输入的几率相同,这个判断可以减少一半的计算量。
3.剪枝:两个奇数之和或者两个偶数之和都是偶数,而偶数一定不是素数,所以在选取当前元素的时候,比较一下它和前一个元素的奇偶性。再做决定,可以减少一部分计算量。
4.位运算按位于判断整数N奇偶性:由于奇数的二进制表示中,最低位是1,N与1按位与运算(N&1)后结果是1,则说明N是一个奇数,否则是一个偶数。即输出结果环中相邻的数奇偶性一定不相同
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 38463 Accepted Submission(s): 17008
Problem Description
A ring is compose of n circles as shown in diagram. Put
natural number 1, 2, …, n into each circle separately, and the sum of numbers in
two adjacent circles should be a prime.
Note: the number of first circle should always be 1.
Input
n (0 < n < 20).
Output
The output format is shown as sample below. Each row represents a series of circle
numbers in the ring beginning from 1 clockwisely and anticlockwisely.
The order of numbers must satisfy the above requirements. Print solutions in
lexicographical order.
You are to write a program that completes above process.
Print a blank line after each case.
Sample Input
6
8
Sample Output
Case 1:
1 4 3 2 5 6
1 6 5 2 3 4
Case 2:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2
深搜的一道水题,原先用C++AC了,因为要学习Java,就用Java撸了一遍。然而悲剧就这么发生了,同样的逻辑代码,符号题目要求的输出,提交了一整天总是presentation error,万般无奈之下去网上搜AC代码,然而没有Java版的,所以只好对着C语言一个个看,后来一步一步调试,才发现要在Case %d:后面再加个空格(可是题目描述和C++版中都没有这个空格)。~~~~,虽然Java运行慢,用Java打比赛的人少,但也不能这么坑人吧!
import java.util.Arrays; import java.util.Scanner; public class Main { public static int kase = 0,n; public static int[] circles = new int[50]; public static boolean[] flag = new boolean[50],primes = new boolean[50]; static boolean DEBUG = false; static void debug(){ System.out.print("***"); } public static void initPrimes(){ Arrays.fill(primes, true); for(int i=2;i<=30;i++){ for(int j=i+i;j<50;j+=i){ if(j%i==0) primes[j] = false; } } primes[0]=primes[1] = false; } public static void DFS(int i){ if(i==n){ if(primes[1+circles[n-1]]){ for(int j=0;j<n;j++){ if(j==n-1) System.out.print(circles[j]); else System.out.print(circles[j]+" "); } System.out.println(); } return ; } else{ for(int j=2;j<=n;j++){ if(flag[j]){ if(primes[j+circles[i-1]]&&((j+circles[i-1])&1)!=0){//相邻的数奇偶性不同,剪枝! flag[j] = false; circles[i] = j; DFS(i+1); flag[j] = true; } } } } return ; } public static void main(String[] args) { // TODO Auto-generated method stub Scanner in = new Scanner(System.in); initPrimes(); while(in.hasNext()){ n = in.nextInt(); //就是这个坑!! System.out.printf("Case %d: \n", ++kase); if(n==1){ System.out.println(1); System.out.println(); continue; } else if((n&1)!=0){ System.out.println(); continue; } Arrays.fill(flag, true); circles[0] = 1; flag[1] = false; DFS(1); System.out.println(); // if(DEBUG) debug(); } } }
note:
1.数据规模小,所以把1~37的所有素数都找到了,打表空间换时间。
2.数据优化:再考虑输入的特点,如果输入N是奇数的话,由于起点从1开始,那么1-N之间一共有N / 2个偶数,N / 2 + 1个奇数,也就是奇数的个数比偶数多一个,那么把这N个数排成一个环,根据鸽巢原理,必然有两个奇数是相邻的,而两个奇数之和是偶数,偶数不是素数,所以我们得出结论,如果输入N是奇数的话,没有满足条件的排列。这样当N是奇数的时候,直接返回即可。如果1-N之间每个数输入的几率相同,这个判断可以减少一半的计算量。
3.剪枝:两个奇数之和或者两个偶数之和都是偶数,而偶数一定不是素数,所以在选取当前元素的时候,比较一下它和前一个元素的奇偶性。再做决定,可以减少一部分计算量。
4.位运算按位于判断整数N奇偶性:由于奇数的二进制表示中,最低位是1,N与1按位与运算(N&1)后结果是1,则说明N是一个奇数,否则是一个偶数。即输出结果环中相邻的数奇偶性一定不相同
相关文章推荐
- Spring Cache
- 用Struts2来完成一个学生注册界面
- 白话Spring(基础篇)---bean的作用域
- [转]Eclipse:Cannot complete the install because of a conflicting dependency
- java并发编程 Lock
- java并发编程 Lock
- SPRING IN ACTION 第4版笔记-第三章ADVANCING WIRING-006-给bean运行时注入值(Environment,Property文件)
- yocto配置好eclipse之后编译多线程配置
- Java学习笔记(五):异常处理
- Java代码注释规范
- Java虚拟机体系结构深入研究总结
- 查看Jar打包的jdk版本
- java集合框架总结
- 关于java中的try-catch-finally语句和return
- SPRING IN ACTION 第4版笔记-第三章ADVANCING WIRING-005-Bean的作用域@Scope、ProxyMode
- Java学习整理系列之ThreadLocal的理解
- Java发送内嵌图片的邮件
- struts2升级
- javase高级教程学习笔记
- JAVA设计模式-代理模式