<?php
#寻找一个满足给定空数和题数要求的随机方案,事先需统计出每题空格数情况队列$m_blk,以及这些题分别有多少个$m_que。
#以下算法将找到一个随机方案,若未找到将返回假值,如果不限题数,请将题数置为不大于0的数。 $m_v = array(); //目标随机方案 $m_blk = array(); //空格数情况,从小到大排列
$m_que = array(); //空格题数 $m_cnt = array(); //取出的某空格数的题数 //$test_level = 0; //测试变量 function CheckQue($i) //检查题数是否够取,$i为已取的相应空格数题的数量
{
global $m_que;
global $m_cnt;
echo " CheckQue ".$i."_".$m_cnt[$i]."<".$m_que[$i]."; ";
return ($m_cnt[$i] <= $m_que[$i]); //取值正常,已经不可能取到这么多题时,返回错误
}
function CheckLimit($num, $blk) //检查剩下的空数与题数是否有可能的解
{
echo " Limit num".$num.", blk".$blk."; ";
global $m_blk;
return $num>=0?($num*$m_blk[count($m_blk)-1]>=$blk && $num*$m_blk[0]<=$blk):true;
}
function CheckMax($blk) //检查一次题库中空数是否存在选出总空数的可能
{
global $m_blk;
global $m_que;
$t = 0;
for($i=0; $i<count($m_que); $t+=$m_que[$i]*$m_blk[$i],++$i);
echo " t ".$t." blk ".$blk."; ";
return $t>=$blk;
} function SituationVR($nNum , $nBlk) //找到一个方案并返回。nNum目标题数,nBlk目标空数,v每题空格数,且从小到大排列
{
//global $test_level;//测试
//$test_level += 1;
//echo "<br>".$test_level.">"; global $m_v;
global $m_blk;
global $m_cnt; $v = array_keys($m_blk); //拷贝一个原空数队列的序列出来作为新数列去取序号,这样使得$m_cnt可准确计数 for ( $i=0; count($v)>0; $m_cnt[$i] -= 1)
{
echo "<br>"."#";
$ii = mt_rand(0,count($v)-1); //取一题空数为$i,并将记录删除已取过的序号,取出来的是序号的序号
$i = $v[$ii]; //空格队列索引
$b = $m_blk[$i]; //空格数
$m_cnt[$i] += 1; //计数
unset( $v[$ii]);
$v = array_values($v);
echo " ii".$ii." i".$i." b".$b."; "; if (!CheckQue($i)) //检查取题数是否正常范围,超出重取,取不出返回假
{
continue;
} array_push($m_v, $b); //进栈
$t = array_sum($m_v); //求当前累积空数
//var_dump($m_v); var_dump($v);echo $t; $ret = CheckLimit( $nNum-count($m_v),$nBlk-$t); if ($ret) //检查满足题数的结果存在的可能性
{
if ($t == $nBlk) //情况一,得到方案返回真
{
return true;
}
else if ($t<$nBlk) //情况二,方案待完成
{
if (SituationVR($nNum ,$nBlk)) //递归,成功返回真失败继续
{
return true;
}
} //其它均为失败方案,继续即可
}
array_pop($m_v); //取值不当,出栈
}
//echo "<br>".$test_level."<";
//$test_level -= 1;
return false; //没有成功返回,默认返回假
} //测试
$m_blk = array(1, 2, 3);
$m_que = array(1, 5, 1);
$m_cnt = array(0, 0, 0, 0, 0);
$nNum = -1; //取几题,不限题数则置为非正数
$nBlk = 10; //取几个空 var_dump($m_blk);
var_dump($m_que);
echo "<br>";
if(CheckMax($nBlk))
{
$bRet = SituationVR($nNum ,$nBlk);//找出一个随机方案
echo "<br>";echo($bRet?"success! ":"failed! "); var_dump($m_v);
} ?>

为了PHP的这个算法 我也是操碎了心,增加了一些限制条件,导致算法变得略微复杂,后来 我还专门写了一个些范围和强度测试代码 ,并且自动检查取值 的正确性,啊其实这也算是另外一个小算法了,PHP不精,费了不少精力,不过好在证明出题算法没有什么问题,而且速度很快,满足了出题需求。

昨天回去的路上还在想,就像他们PHP的,宁愿写些半拉子代码也不愿去写个万能的算法最后非要等到别人送到嘴边才肯用。历害的是不是很多都是“业余的”,被跨专业打败。

常常喜欢用一个简洁的写法,这样也会带来一些阅读上的困难,严重的会引入逻辑上的错误,但是这也阻挡不了写法上的极致体验带来的爽感。

适用于填空题出题 的随机算法 PHP的更多相关文章

  1. 【Warrior刷题笔记】力扣169. 多数元素 【排序 || 哈希 || 随机算法 || 摩尔投票法】详细注释 不断优化 极致压榨

    题目 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/majority-element/ 注意,该题在LC中被标注为easy,所以我们更多应该关 ...

  2. LOJ #2540. 「PKUWC 2018」随机算法(概率dp)

    题意 LOJ #2540. 「PKUWC 2018」随机算法 题解 朴素的就是 \(O(n3^n)\) dp 写了一下有 \(50pts\) ... 大概就是每个点有三个状态 , 考虑了但不在独立集中 ...

  3. HDU 4712 Hamming Distance(随机算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4712 解题报告:输入n个数,用十六进制的方式输入的,任意选择其中的两个数进行异或,求异或后的数用二进制 ...

  4. 随机算法 - HNU 13348 Finding Lines

    Finding Lines Problem's Link: http://acm.hnu.cn/online/?action=problem&type=show&id=13348&am ...

  5. [PKUWC2018]随机算法

    题意:https://loj.ac/problem/2540 给定一个图(n<=20),定义一个求最大独立集的随机化算法 产生一个排列,依次加入,能加入就加入 求得到最大独立集的概率 loj25 ...

  6. 浅浅地谈一下随机算法【poj2454】【poj3318】

    随机算法我也只是稍微接触了一下,就是想写篇博客自己稍微总结一下 其实随机算法也算是一个玄学吧,运气不好还是会wa.但是我们知道,计算机可以在短时间内计算大量的数据,所以碰到正确答案的概率还是挺大的. ...

  7. 【洛谷5492】[PKUWC2018] 随机算法(状压DP)

    点此看题面 大致题意: 用随机算法求一张图的最大独立集:每次随机一个排列,从前到后枚举排列中的点,如果当前点加入点集中依然是独立集,就将当前点加入点集中,最终得到的点集就是最大独立集.求这个随机算法的 ...

  8. [BJOI2014]想法(随机算法,神奇思路,拓扑排序)

    对于这种随机数据或者随机算法的题-- 都是神仙题吧. 要求的就是对每个点前 \(m\) 个点中有多少个可以到达它. 由于评分方式这么奇怪,不妨考虑随机. 随机 127 次(可以选别的数,够多而且不 T ...

  9. [Codeforces 364D]Ghd(随机算法+gcd)

    [Codeforces 364D]Ghd(随机算法) 题面 给出n个正整数,在其中选出n/2(向上取整)个数,要求这些数的最大公约数最大,求最大公约数的最大值 分析 每个数被选到的概率\(\geq \ ...

随机推荐

  1. Linux监控命令之==>vmstat

    一.使用说明 vmstat 可以对操作系统的内存信息.进程状态.CPU 活动.磁盘等信息进行监控,不足之处是无法对某个进程进行深入分析. 二.用法及参数说明 -a:显示活跃和非活跃内存 -f:显示从系 ...

  2. LeetCode算法题-Goat Latin Easy(Java实现)

    这是悦乐书的第322次更新,第344篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第192题(顺位题号是824).给出句子S,由空格分隔的单词组成.每个单词仅由小写和大写 ...

  3. 操作系统(5)实验0——makefile的写法

    之前GCC那部分我提到过,gcc啥啥啥啥傻傻的那个指令只能够编译简单的代码,如果要干大事(例如突然心血来潮写个c开头的神经网络库之类的),还是要写Makefile来编译.其实在Windows下通常用I ...

  4. EFI系统分区如何删除

    U盘或者硬盘被做了系统安装盘. 结果在格式化都是失败,分区也不行. 有了新招 EFI分区是您的系统启动引导的分区,存放引导启动的文件的,因此它是一个操作系统独立的分区,实际上它是UEFI加载的固件和应 ...

  5. (转)Eclipse - CDT使用GDB调试C++的问题-无源文件命名(No source file named)

    http://tech.ddvip.com/2014-09/1411618782213496.html Eclipse CDT调试C++, 使用的Unix的调试器GDB; 由于在Unix下, 文件的目 ...

  6. 20191127 Spring Boot官方文档学习(5)

    5.Spring Boot Actuator:可投入生产的功能 Spring Boot包含许多其他功能,可帮助您在将应用程序投入生产时监控和管理您的应用程序.您可以选择使用HTTP端点或JMX管理和监 ...

  7. 使用Oracle12c 以上的PDB创建数据库用户 密码过期的简单处理

    1. 先通过监听查看PDB的名字 Windows 打开命令行: 输入命令 lsnrctl status 一般在如图示的最下面 2. 也可以通过GS的全局配置文件来查看 数据库连接SID信息. C:\P ...

  8. CSS中BFC规则

    何为BFC BFC(Block formatting context)直译为"块级格式化上下文".它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的B ...

  9. Python list和tuple的相互转换?

    list转为tuple: temp_list = [1,2,3,4,5] 将temp_list进行强制转换:tuple(temp_list) 查看是否转换成功:print type(temp_list ...

  10. P2523 [HAOI2011]Problem c

    传送门 先考虑如何判断无解,设 $sum[i]$ 表示确定的人中,编号大于 $i$ 的人的人数 如果 $sum[i]>n-i+1$ 则无解,进一步考虑设 $f[i][j]$ 表示当前确定完编号大 ...