仿人通过的1011

本文介绍了一个Java程序,用于解决给定一组数字后寻找能够将这些数字划分为几个相等子集的问题。通过输入一系列整数并利用递归算法尝试找到合适的组合方式,使每个子集的总和相等。该程序采用因子分解的方法来缩小搜索范围,提高了解决问题的效率。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		new Main();
	}

	int count;// 数字个数

	int[] a;
	boolean[] b;

	int L;// 当前匹配长度

	public Main() {
		Scanner s = new Scanner(System.in);
		while (s.hasNextInt()) {
			count = s.nextInt();
			if (count == 0) {
				break;
			}

			a = new int[count];
			b = new boolean[count];

			int sum = 0;
			for (int i = 0; i < count; i++) {
				int num = s.nextInt();
				sum += num;
				a[i] = num;
			}
			Arrays.sort(a);

			int max = a[count - 1];

			// 遍历可能的匹配长度
			for (int i : getList(sum)) {
				if (max <= i) {
					L = i;
					if (exec(count - 1, i, sum)) {
						System.out.println(i);
						break;
					}
				}
			}

		}

		s.close();

	}

	public boolean exec(int begin, int left, int all) {
		if (left == 0) {
			all -= L;
			if (all == 0) {
				return true;
			} else {
				left = L;
				begin = count - 2;// 从第二个数开始继续匹配,其实可以从第一个可用数开始匹配
			}
		}
		while (begin >= 0) {
			if (!b[begin]) {// 可用
				int n = a[begin];
				if (n <= left) {// 未过界
					b[begin] = true;// 假设使用了
					if (exec(begin - 1, left - n, all)) {
						return true;
					} else {
						b[begin] = false;// 还原
						if (left == L || left == n) {// 如果是首个或末个长度匹配失败,直接退出
							break;
						}
					}
				}
				while (--begin >= 0 && a[begin] == n) {// 下一个不同的数

				}
				int tleft = left;// 剩余之和是否足够
				for (int j = begin; j >= 0; j--) {
					if (!b[j]) {
						tleft -= a[j];
						if (tleft <= 0) {
							break;
						}
					}
				}
				if (tleft > 0) {
					break;
				}
			} else {
				begin--;
			}
		}

		return false;
	}

	// 获得所有因子,从小到大排序
	public List<Integer> getList(int n) {
		List<Integer> list = new ArrayList<Integer>();
		for (int i = 1; i <= Math.sqrt(n); i++) {
			if (n % i == 0) {
				list.add(i);
				if (i * i != n) {
					list.add(n / i);
				}
			}
		}
		Collections.sort(list);
		return list;
	}
}
 

http://blog.youkuaiyun.com/night_blue/archive/2008/09/23/2966056.aspx

比原作者的代码慢100毫秒多

### 四表决电路的设计思路 #### 功能描述 我们需要设计一个四表决电路,其中: - A 的权重为 2 分; - B、C 和 D 每的权重均为 1 分。 当 **总分 ≥ 3** 时,结果 `Y` 输出为 `1`;否则输出为 `0`。 我们可以将输入信号表示为四位二进制数 `[A, B, C, D]`,并计算得分公式: ``` Score = 2 * A + B + C + D 如果 Score >= 3,则 Y = 1;否则 Y = 0。 ``` 接下来我们将采用 Verilog HDL 来实现该功能模块和顶层模块。 --- ### 设计步骤 #### 第一步:定义功能模块 (`voter_module`) 这是一个核心的功能模块,用于完成加权评分及条件判断。 ```verilog // 定义功能模块 voter_module module voter_module ( input wire a, b, c, d, output reg y ); always @(*) begin // 计算分数 int score; score = (a ? 2 : 0) + (b ? 1 : 0) + (c ? 1 : 0) + (d ? 1 : 0); // 判断是否满足条件 if(score >= 3) y <= 1'b1; // 如果分数≥3,输出为1 else y <= 1'b0; // 否则输出为0 end endmodule ``` #### 第二步:创建顶层测试模块 (`top_module_testbench`) 为了验证我们的设计是否正确工作,可以编写一个测试平台(Test Bench),对所有可能的输入组合进行仿真。 ```verilog // 测试台 top_module_testbench module top_module_testbench; reg a, b, c, d; wire y; // 实例化功能模块 voter_module uut (.a(a), .b(b), .c(c), .d(d), .y(y)); initial begin $display("Testing Voter Module..."); $monitor("At time %t: Inputs=%b%b%b%b -> Output=%b", $time, a, b, c, d, y); // 枚举所有可能性 {a,b,c,d} = 4'b0000; #10; {a,b,c,d} = 4'b0001; #10; {a,b,c,d} = 4'b0010; #10; {a,b,c,d} = 4'b0011; #10; {a,b,c,d} = 4'b0100; #10; {a,b,c,d} = 4'b0101; #10; {a,b,c,d} = 4'b0110; #10; {a,b,c,d} = 4'b0111; #10; {a,b,c,d} = 4'b1000; #10; {a,b,c,d} = 4'b1001; #10; {a,b,c,d} = 4'b1010; #10; {a,b,c,d} = 4'b1011; #10; {a,b,c,d} = 4'b1100; #10; {a,b,c,d} = 4'b1101; #10; {a,b,c,d} = 4'b1110; #10; {a,b,c,d} = 4'b1111; #10; $finish; end endmodule ``` --- ### 运行与调试 运行上述代码后,在波形窗口或控制台上可以看到每个输入对应的输出状态。例如: - 输入 `{A,B,C,D}` 为 `1011` (即 A=2分+B=1分+C=1分+D=1分 总分为5)时,输出应为 `1`。 - 输入 `{A,B,C,D}` 为 `0111` (B=1分+C=1分+D=1分 总分为3)时,输出也应为 `1`。 - 其他类似情况均需逐一验证。 --- ### 结论 以上就是如何基于 Verilog HDL 使用“与”、“非”等基本逻辑运算符构建一个简单但实用的表决系统的过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值