杭电ACM1016解题报告(Java)

14 篇文章 0 订阅


==========================================真情推荐=========================================================
给大家推荐一个很吊的网站(钱宝网),个人感觉和阿里巴巴的余额宝类似,不过收益大约是余额宝的5~10倍。收益用来充话费
是足够了。并且注册就送6.6元,可立马提现。本人其身体验,保证网站真实可信。由于CSDN不允许贴推广链接。大家如果感兴趣
可以搜索“钱宝网”,第一个就是。请大家注册的时候填写激活码: 5135745
===========================================================================================================

1、题目概述


该题目是一道简单的搜索类题目,通过枚举+判断找出所有的答案。


2、题目分析

问题:


给定一个整数n,按字典序输出所有的质数环。


条件:


1、Put natural number 1, 2. ..., n into each circle separately.(将自然数1-n分别放入不同的圈内)


2、and the sum of number in two adjacent circles should be a prime.(并且相邻的圈内的两个数字之和为质数)


3、Print solutions in lexicographical order.(将所有的结果按字典序输出)


3、算法设计


算法比较简单,就是:枚举+判断,如果结果满足要求就输出。

剪枝:这里有一个比较重要的剪枝,通过观察可发现,当n为奇数的时候,n+1必为偶数,所以此时不可能有符合条件的素数环。


4、编程方式


编写一个递归搜索函数,递归搜索的普遍做法是:先写出退出条件,然后再写自身递归

数据结构:

result[],用于记录枚举的方案

used[],为一个hash表,used[i]标记数字i有没有出现在前面的枚举方案中

另外,为了提高输出效率,我们可以先将结果暂时存储在一个缓冲数组内,最后一起把结果输出。


5、代码(Java描述)

import java.util.Arrays;
import java.util.Scanner;

public class Main {
	
	public static int[] result = new int[25];
	public static boolean[] visited = new boolean[25];
	
	public static boolean[] is_prime_table = new boolean[100];
	public static void generateIs_prime_table() {
		Arrays.fill(is_prime_table, true);
		is_prime_table[0] = is_prime_table[1] = false;
		for(int i = 2; i < 100; i ++) {
			if(is_prime_table[i]) {
				for(int k = i * i; k < 100; k += i) {
					is_prime_table[k] = false;
				}
			}
		}
	}
	
	public boolean isPrime(int num) {
		return is_prime_table[num];
	}
	
	public void dfs(StringBuilder sb, int cur, int total) {
		if(total % 2 == 1) {
			return;
		}
		if(cur == total + 1) {
			if(isPrime(result[total] + result[1])) {
				for(int i = 1; i < total; i ++) {
					sb.append(result[i] + " ");
				}
				sb.append(result[total] + "\r\n");
			}
			return;
		}
		for(int i = 2; i <= total; i ++) {
			if(visited[i] == false && isPrime(result[cur - 1] + i)) {
				visited[i] = true;
				result[cur] = i;
				dfs(sb, cur + 1, total);
				visited[i] = false;
			}
		}
	}
	public StringBuilder getAns(int cas, int n) {
		StringBuilder ret = new StringBuilder();
		ret.append("Case ").append(cas).append(":\r\n");
		Arrays.fill(visited, false);
		visited[1] = true;
		result[1] = 1;
		dfs(ret, 2, n);
		return ret;
	}
	
	public static void main(String[] args) {
		generateIs_prime_table();
		Scanner cin = new Scanner(System.in);
		int cas = 1;
		while(cin.hasNext()) {
			int n = cin.nextInt();
			Main obj = new Main();
			StringBuilder sb = obj.getAns(cas, n);
			cas ++;
			System.out.println(sb.toString());
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值