1:
已知开始有n个数(从1,2,3...n)围在一个圆周围。从第1个开始报数,数到m的那个数时:
(1)如果这个数x是偶数,就把这个数分裂成2个x/2的数;
(2)否则(x为奇数),则出列(删除这个数);
然后从下一个数开始又从1开始报数,数到m的那数又同上处理;依此规律重复下去,直到全部数出列。依次输出出列的数。
例如n=5,m=3:
开始 | 1 2 3 4 5 | 输出3 |
第1轮 | 1 2 4 5 | 输出1 |
第2轮 | 2 4 5 | 输出5 |
第3轮 | 2 4 | |
第4轮 | 1 1 4 | 输出1 |
第5轮 | 1 4 | |
第6轮 | 1 2 2 | |
第7轮 | 1 2 1 1 | 输出1 |
第8轮 | 1 2 1 | |
第9轮 | 1 1 1 1 | 输出1 |
第10轮 | 1 1 1 | 输出1 |
第11轮 | 1 1 | 输出1 |
第12轮 | 1 | 输出1 |
说明:从红色的数开始,将数到黄色的位置
输入格式
第一行2个正整数N和M,N范围在[2,10000],M范围在[1,1000]。
输出格式
一行,多个整数。
输入/输出例子1
输入:
5 3
输出:
3 1 5 1 1 1 1 1 1
#include<bits/stdc++.h>
using namespace std;
int n,k,m;
struct Tnode{ //节点的类型
int val; //节点的数据
int next; //下一个节点的位置 --数组下标
};
Tnode a[1000005] ; //存放节点的数组
int ap=0; //数组a的空闲位置
int head; //头指针 --- 第一个节点的位置(下标)
//在下标为p的节点后面插入数值为x的新节点
void insert(int p, int x){
int q=ap++; //取得一个新节点
a[q].val=x;
a[q].next = a[p].next;
a[p].next = q;
}
//下标为p的节点向后移动m个
int nextM(int p, int m){
while (m--)
p=a[p].next;
return p;
}
//删除下标为p的节点后面的节点
void del(int p){
a[p].next = a[ a[p].next].next;
}
void init(){
//本题初始化
for (int i=1; i<=n; i++) {
a[i].val = i;
a[i].next = i+1;
}
a[n].next = 1; //构成环
ap=n+1; // 重要,容易漏!
}
int main()
{
cin >> n >> m;
init();
//报数出队
int p=n;
int count =n;
while ( count>0 ) {
p=nextM(p, m-1 ); //p向后移动
int q=a[p].next;
if (a[q].val%2==1){
cout << a[q].val<<" ";
del(p);
count--;
} else {
int y=a[q].val/2;
a[q].val=y; //分裂为一半
insert(q,y); //插入新节点
p=nextM(p,2); //到这2个节点后面
count++;
}
}
return 0;
}
2:
已知开始有n个非零整数围在一个圆周围。从第1个开始:
(1)如果这个数x是正数,就把这个数x删除,并向后移x个数;
(2)否则(x为负数),就把这个数x删除,并向前移|x|个数;
然后从到达的数开始,依此规律重复下去,直到全部数出列。依次输出删除的数。
例如n=5,5个数为2 3 1 -1 1:
开始 | 2 3 1 -1 1 | 输出2 |
第1轮 | 3 1 -1 1 | 输出1 |
第2轮 | 3 -1 1 | 输出-1 |
第3轮 | 3 1 | 输出3 |
第4轮 | 1 | 输出1 |
说明:从红色的数开始,将到达黄色的位置
输入格式
第一行1个正整数N,N范围在[2,100000]。
第二行N个非0整数,范围[-1000,1000]且不为0。
输出格式
一行,N个整数。
输入/输出例子1
输入:
5
2 3 1 -1 1
输出:
2 1 -1 3 1
#include<bits/stdc++.h>
using namespace std;
struct Node{
int val;
int next;
int pre;
}a[100001];
int n,ap=0;
void delNode(int p)
{
a[a[p].pre].next=a[p].next;
a[a[p].next].pre=a[p].pre;
}
void insert(int p,int x)
{
int q=ap++;
a[q].val=x;
a[q].next=a[p].next;
a[a[p].next].pre=q;
a[q].pre=p;
a[p].next=q;
}
int nextM(int p, int m){
while (m)
{
p=a[p].next;
m--;
}
return p;
}
int preM(int p, int m){
while (m)
{
p=a[p].pre;
m--;
}
return p;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
a[i].val=x;
a[i].next=i+1;
a[i].pre=i-1;
}
a[n].next=1;
a[1].pre=n;
int count=n;
int p=1;
while(count>0)
{
cout<<a[p].val<<" ";
delNode(p);
count--;
if(a[p].val>0)
{
p=nextM(p,a[p].val);
}
else
{
p=preM(p,-a[p].val);
}
}
return 0;
}