[洛谷]p1996约瑟夫环 &xdoj1311
https://www.luogu.org/problemnew/show/P1996
约瑟夫环这个问题一直以来都是用循环链表写的,今天才知道有循环队列的写法。以下是要点:
1.循环队列实现环的思想,其实就是队首元素出队,如果它不是该出队的元素,那么就把它继续push进queue,这样就构成了一个环的结构。
2.用一个辅助变量来记录每次要进行的操作,比如每三个人出来选出一个人,temp设置为2,先连续两次出队再入队,此时队首就是该出队的那个元素,把它直接pop扔掉即可。循环执行,直至所有元素出队,打印结果。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, m;
scanf("%d %d", &n, &m);
queue<int>Q;
int i;
for (i = ; i <= n; i++)
{
Q.push(i);
}
int temp;
int a;
while (!Q.empty())
{
temp = m-;
while (temp)
{
a = Q.front();
Q.pop();
Q.push(a);
temp--;
}
a = Q.front();
Q.pop();
printf("%d ", a);
}
}
下面再说一下常规的循环链表写法:
1.这个循环链表一定要是双向的链表有prior和next两个指针,如果只有一个指针,删除中间结点的操作无法完成。
2.计数的时候就用简单粗暴的temp辅助变量来完成计数,用cnt从0加到n再置0那种方法容易出错。
#include <bits/stdc++.h>
using namespace std;
typedef struct LNode
{
int data;
struct LNode*prior;
struct LNode*next;
}LNode;
void creat(LNode*&L, int n)
{
LNode*r;
r = L;
LNode*s;
int i;
r->data = ;
for (i = ; i <= n; i++)
{
s = (LNode*)malloc(sizeof(LNode));
s->data = i;
r->next = s;
s->prior = r;
r = r->next;
}
r->next = L;
L->prior = r;
}
void delete1(LNode*&L, int m,int n)
{
int cnt=;
LNode*r;
LNode*s;
r = L;
int temp;
while (n)
{
temp = m-;
while (temp)
{
r = r->next;
temp--;
}
s = r;
printf("%d ", s->data);
r->prior->next = r->next;
r->next->prior = r->prior;
r = r->next;
free(s);
n--;
} }
int main()
{
int n, m;
scanf("%d %d", &n, &m);
LNode *L;
L = (LNode*)malloc(sizeof(LNode));
creat(L, n);
delete1(L,m,n);
}
http://acm.xidian.edu.cn/problem.php?id=1311
下面这道xdoj1311这道题很有意思,仔细想想和约瑟夫队列很相似。
1.第一点就是要想到的是用队列实现环状结构。
2.奇数回合抽出所有2的倍数的编号,偶数回合抽出所有3的倍数的编号。这个实现其实很简单,偶数就是1234每隔两张抽出1张牌,其实就是temp=1进行一次队首移动到队尾的操作,然后现在队首的元素就是该抽出的元素。3同理,移动队首元素两次即可。
3.与约瑟夫环不同的是约瑟夫环是一个循环走到黑直至队空,而这个是很多回合每个回合都要把所有的牌搞一遍,仔细想想就会发现设置t也就是回合次数,可以完成所有牌的遍历,但有一点非常容易错的地方在于,执行完t次操作之后,你的队首元素不再是1(1既不是2的倍数也不是3的倍数始终未被抽出)。要实现队首元素为1就可以等效为每次都是从1开始的,与一条线性的队列没差别了。这里巧妙的用一个while的循环来保证每次队首的元素都是1.这样问题就解决了。
4.最后要实现队列剩余元素的顺序打印就十分简单了,全放在vector中,然后sort排序,输出即可。
整道题目像是一个加强版的约瑟夫,有些细节还是需要注意的。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T;
scanf("%d", &T);
int n;
queue<int>Q;
while (T--)
{
int cnt = ;
scanf("%d", &n);
int i;
int m;
for (i = ; i <= n; i++)
{
Q.push(i);
}
int temp;
int t;
while (Q.size() > )
{
if (cnt % != )
{
t = Q.size() / ;
while (t--)
{
temp = ;
while (temp--)
{
m = Q.front();
Q.pop();
Q.push(m);
}
Q.pop();
}
while (Q.front() != )
{
m = Q.front();
Q.pop();
Q.push(m);
}
}
else
{
t = Q.size() / ;
while (t--)
{
temp = ;
while (temp--)
{
m = Q.front();
Q.pop();
Q.push(m);
}
Q.pop();
}
while (Q.front() != )
{
m = Q.front();
Q.pop();
Q.push(m);
}
}
cnt++;
}
vector<int>v;
while (!Q.empty())
{
v.push_back(Q.front());
Q.pop();
}
sort(v.begin(), v.end());
for (i = ; i < v.size(); i++)
{
if (i != v.size() - )
printf("%d ", v[i]);
else
printf("%d", v[i]);
}
printf("\n");
}
}
[洛谷]p1996约瑟夫环 &xdoj1311的更多相关文章
- 【新知识】队列&bfs【洛谷p1996约瑟夫问题&洛谷p1451求细胞数量】
(是时候为五一培训准备真正的技术了qwq) part1 队列(FIFO) 算法简介: FIFO:First In First Out(先进先出) 队列是限定在一端进行插入,另一端进行删除的特殊线性表 ...
- 【vector的输出问题】 洛谷 P1996 约瑟夫问题
题目:P1996 约瑟夫问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 可恶啊,本来是一道不算难的题,硬是因为cin,cout同步流卡了我一天qwq 关闭cin,cout同步流 ...
- 洛谷——P1996 约瑟夫问题
P1996 约瑟夫问题 (什么?!要给学弟学妹讲约瑟夫问题?!难道就不怕我给他们讲错了吗?! 啊啊啊,为了不给学弟学妹们讲错,蒟蒻表示要临阵磨一下刀...) 题目背景 约瑟夫是一个无聊的人!!! 题目 ...
- 洛谷P1996 约瑟夫问题【链表】
题目:https://www.luogu.org/problemnew/show/P1996 题意: 约瑟夫环.每次取出第m个,第2m个...... 思路: 链表维护.[感觉很少有用到链表.]非常经典 ...
- 洛谷 P1996 约瑟夫问题
题目背景 约瑟夫是一个无聊的人!!! 题目描述 n个人(n<=100)围成一圈,从第一个人开始报数,数到m的人出列,再由下一个人重新从1开始报数,数到m的人再出圈,……依次类推,直到所有的人都出 ...
- (水题)洛谷 - P1996 - 约瑟夫问题 - 链表
https://www.luogu.org/problemnew/show/P1996 试了一下数组实现的双向链表,是挺难用的,估计是应该写个get_next()函数比直接用next数组好. #inc ...
- 洛谷P1996 约瑟夫问题【队列】
题目背景 约瑟夫是一个无聊的人!!! 题目描述 n个人(n<=100)围成一圈,从第一个人开始报数,数到m的人出列,再由下一个人重新从1开始报数,数到m的人再出圈,--依次类推,直到所有的人都出 ...
- 【洛谷P1996】约瑟夫问题
约瑟夫问题 链表模拟大概是正解 #include<iostream> using namespace std; struct node{ //单链表 int d; node *next; ...
- 洛谷P3385负环
传送门 #include <iostream> #include <cstdio> #include <cstring> #include <algorith ...
随机推荐
- 洛谷 P1223排队接水【贪心】
题目描述 有n个人在一个水龙头前排队接水,假如每个人接水的时间为Ti,请编程找出这n个人排队的一种顺序,使得n个人的平均等待时间最小. 输入输出格式 输入格式: 输入文件共两行,第一行为n:第二行分别 ...
- 洛谷 P1090合并果子【贪心】【优先队列】
题目描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和.可 ...
- cmd打开E盘文件
在命令行中输入你想要打开文件所在的磁盘,这里我以打开E:\homework\1.jpg来给大家做示范.在命令行中输入 E: 输入后按下enter键.就进入E盘中,效果如图所示! 如果你想要查 ...
- ASP.NET异步
1.ASP.NET线程模型 在WEB程序中,天生就是多线程的,我们知道,一个WEB服务可以同时服务器多个用户,我们可以想象一下,WEB程序应该运行于多线程环境中,对于运行WEB程序的线程,我们可以称之 ...
- eclipse安装Hadoop-0.20.2插件
因为在使用Hadoop-0.20.2这个古董,需要使用它自带的eclipse插件,而我最初安装的是现代的eclipse4.10.0. 在经历两天,以及以下种种尝试之后,均以失败告终: 1.网上找适合的 ...
- [No000017C]改善C#程序的建议5:引用类型赋值为null与加速垃圾回收
在标准的Dispose模式中(见前一篇博客“C#中标准Dispose模式的实现”),提到了需要及时释放资源,却并没有进一步细说让引用等于null是否有必要. 有一些人认为等于null可以帮助垃圾回收机 ...
- [No0000B2]ReSharper操作指南3/16-配置ReSharper与代码校错
配置ReSharper ReSharper功能具有默认配置,这些配置基于.NET世界中的约定和最佳实践.但是,每个功能都可以根据您的需求和喜好灵活调整. ReSharper首选项可以在以下位置进行配置 ...
- angularjs 在 iframe 里面无法正确显示 src 指定的内容
原 controller : $scope.myURL = URL; 页面: <iframe ng-src='{{myURL}}' class="width-100 height-10 ...
- 栈帧 2.6. Frames 虚拟机内存模型
https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-2.html#jvms-2.6 小结: 1. https://docs.oracle. ...
- Diagnosing out of memory errors and memory leaks 内存泄露实例 C Java JavaScript 内存泄露
小结: 1. 数据库连接池. JDBC语句和结果对象必须显式地关闭. 2. 电梯到目标楼层后地址是否被释放 When a button is pressed: Get some memory, whi ...