洛谷 P1145:[CERC 1995] 约瑟夫 ← 队列 + 优化
【题目来源】https://www.luogu.com.cn/problem/P1145【题目描述】2k 个人站成一圈从某个人开始数数每次数到 m 的人就被杀掉然后下一个人重新开始数直到最后只剩一个人。现在有一圈人k 个好人站在一起k 个坏人站在一起。从第一个好人开始数数。你要确定一个最小的 m使得在 k 个坏人均被杀死时 k 个好人都存活。【输入格式】一行一个整数 k。【输出格式】一行一个整数 m。【输入样例一】3【输出样例一】5【输入样例二】4【输出样例二】30【数据范围】0k14。【算法分析】● 注意题目中的关键陈述“k 个好人站在一起k 个坏人站在一起。从第一个好人开始数数”这个代码会直接体现。● 由于所有人始终围成一圈进行报数当报数次数恰好等于当前队列总人数时相当于绕圈一周后回到起点。因此在如下代码中模拟报数过程时不必真的执行完整的m-1次移动操作只需通过取模运算(m-1) % len计算出有效偏移步数直接跳过所有绕圈的冗余操作。这一优化能将原本可能高达数万次的循环骤减为最多几十次大幅降低时间开销从而避免程序超时。--- 这就是这道题必须加、不加必超时TLE的优化策略【算法代码】#include bits/stdc.h using namespace std; bool check(int k,int m) { queueint q; //First good k people, then bad. for(int i1; i2*k; i) q.push(i); for(int i0; ik; i) { //Kill k bad. int lenq.size(); int step(m-1)%len; for(int j0; jstep; j) { q.push(q.front()); q.pop(); } //Dequeue the mth element int tq.front(); q.pop(); //If killed good, failure. if(tk) return false; } return true; } int main() { int k,m1; cink; while(true) { if(check(k,m)) { coutmendl; break; } m; } return 0; } /* in:3 out:5 */【参考文献】https://blog.csdn.net/hnjzsyjyj/article/details/149135096https://blog.csdn.net/hnjzsyjyj/article/details/108410252https://blog.csdn.net/hnjzsyjyj/article/details/127023239https://blog.csdn.net/hnjzsyjyj/article/details/133636109
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2449561.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!