抽签问题与二分搜索

在这里插入图片描述

四重循环的复杂度为O(n4)若1<=n<=1000则为n12,不能满足要求。


#include<cstdio>

const int max_n = 50;
int main() {
	int n, m, k  [max_n];
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++) {
		scanf("%d", k[i]);
	}
	bool f = false;
	//通过四重循环枚举所有方案
	for (int a = 0; a < n; a++) {
		for (int b = 0; b < n; b++) {
			for (int c = 0; c < n; c++) {
				for (int d = 0; d < n; d++) {
					if (k[a] + k[b] + k[c] + k[d] == m) {
						f = true;
					}
				}
			}
		}
	}
	if (f)puts("yes");
	else puts("no");

	return 0;
}

故需要改进
这里使用二分搜索与O(n^3logn)的算法
*排序O(nlogn)时间;
*循环O(n^3logn)时间;

#include<cstdio>
#include<iostream>
const int max_n = 50;
int n, m, k[max_n];
bool binary_search(int x) {
//x的存在范围是k[1],k[2].....k[r-1]
	int l = 0, r = n;
	//反复操作直到存在范围为空
	while (r - 1 >= 1) {
		int i = (l + r) / 2;
		if (k[i] == x)return true;
		else r = i;
	}//没找到x
	return false;
}
void solve() {
//为了二分查找先排序
	sort(k, k + n);
	bool f = false;
	for (int a = 0; a < n; a++) {
		for (int b = 0; b < n; b++) {
			for (int c = 0; c < n; c++) {
				//将最内侧的循环替换成二分查找
				if (binary_search(m-k[a]-k[b]-k[c])) {
						f = true;
					}
				
			}
		}
	}
	if (f)puts("yes");
	else puts("no");
}

可以利用等式关系,使用O(n^2logn)的算法
即找到k(c)+K(d)=m-k(a)-k(b)是否存在,需要先将c、d组合的n^2个数字排好序
再使用二分搜索
*排序O(n^2logn)时间;
*循环O(n^2logn)时间;

int n, m, k[max_n];
int kk[max_n * max_n];
bool binary_search(int x) {
	int l = 0, r = n*n;
	while (r - 1 >= 1) {
		int i = (l + r) / 2;
		if (kk[i] == x)return true;
		else if (kk[i] < x)l = i + 1;
		else r = i;
	}
	return false;
}
void solse() {
	for (int c = 0; c < n; c++) {
		for (int d = 0; d < n; d++) {
			kk[c * n + d] = k[c] + k[d];
		}
	}
	sort(kk, kk + n * n);
	bool f = false;
	for (int a = 0; a < n; a++) {
		for (int b = 0; b < n; b++) {			
			if (binary_search(m - k[a] - k[b] )) {
					f = true;
				}			
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的HTML和JavaScript代码,可以实现抽签分小组功能: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>抽签分组</title> </head> <body> <h1>抽签分组</h1> <p>请输入学生名单,每个名字用逗号隔开:</p> <textarea id="student-list"></textarea> <p>请输入每组的人数:</p> <input type="number" id="group-size" min="1" value="3"> <button onclick="drawLots()">抽签分组</button> <h2>分组结果</h2> <div id="group-result"></div> <script> function drawLots() { var studentList = document.getElementById("student-list").value.split(","); var groupSize = parseInt(document.getElementById("group-size").value); var numGroups = Math.ceil(studentList.length / groupSize); var groups = new Array(numGroups); for (var i = 0; i < numGroups; i++) { groups[i] = new Array(); } for (var i = 0; i < studentList.length; i++) { var groupIndex = i % numGroups; groups[groupIndex].push(studentList[i]); } var resultHtml = ""; for (var i = 0; i < numGroups; i++) { resultHtml += "<h3>第 " + (i + 1) + " 组:</h3>"; resultHtml += "<ul>"; for (var j = 0; j < groups[i].length; j++) { resultHtml += "<li>" + groups[i][j] + "</li>"; } resultHtml += "</ul>"; } document.getElementById("group-result").innerHTML = resultHtml; } </script> </body> </html> ``` 这个代码包含一个文本框,让用户输入学生名单,一个数字输入框,让用户输入每组的人数,以及一个按钮,当用户点击按钮时,会调用 `drawLots()` 函数进行抽签分组。该函数按照以下步骤进行操作: 1. 获取用户输入的学生名单和每组的人数。 2. 计算需要分成多少组,并创建一个二维数组 `groups` 来存储每组的学生名单。 3. 遍历学生名单,将每个学生随机分配到一个组中。 4. 根据 `groups` 数组生成 HTML 输出结果。 在结果中,每个小组的学生名单会以无序列表的形式展示出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值