题目描述
Corporal Klinger is a member of the 4077th Mobile Army Surgical Hospital in the Korean War; and he will do just about anything to get out. The U.S. Army has made an offer for a lottery that will choose some number of lucky people (X) to return to the states for a recruiting tour. Klinger needs your help getting out.
The lottery is run by lining up all the members of the unit at attention and eliminating members by counting off the members from 1 to N where N is a number chosen by pulling cards off of the top of a deck. Every time N is reached, that person falls out of the line, and counting begins again at 1 with the next person in line. When the end of the line has been reached (with whatever number that may be), the next card on the top of the deck will be taken, and counting starts again at 1 with the first person in the remaining line. The last X people in line get to go home.
Klinger has found a way to trade a stacked deck with the real deck just before the selection process begins. However, he will not know how many people will show up for the selection until the last minute. Your job is to write a program that will use the deck Klinger supplies and the number of people in line that he counts just before the selection process begins and tell him what position(s) in the line to get in to assure himself of a trip home. You are assured that Klinger's deck will get the job done by the time the 20th card is used.
A simple example with 10 people, 2 lucky spots, and the numbers from cards 3, 5, 4, 3, 2 would show that Klinger should get in positions 1 or 8 to go home.
输入
输出
样例输入
10 2 3 5 4 3 2 9 6 10 10 6 2 6 7 3 4 7 4 5 3 2
47 6 11 2 7 3 4 8 5 10 7 8 3 7 4 2 3 9 10 2 5 3
样例输出
Selection #1
1 8
Selection #2
1 3 16 23 31 47
约瑟夫问题,但是就是格式有点坑。
AC:
#include<iostream>
#include<string.h>
using
namespace
std;
int
st[22],en[100]={0};
int
main()
{
int
i,j,m,n,flag,len,t=0;
while
(
scanf
(
"%d"
,&m)!=EOF) //这里要判断输入结束,否则输出超限
{
cin>>n;
t++;
for
(i=0;i<20;i++)
cin>>st[i];
len=m;
memset
(en,0,
sizeof
(en));
//***每次的en【】数组置零,错了好几次在这个地方,要不然后面的输入会受前面输入的影响。出错
for
(i=0;i<20&&len!=n;i++)
{
int
k=st[i];
int
count=0;
for
(j=0;j<m&&len!=n;j=j+1) //这个地方是从题目中看出来的,每个k只保留一圈(j<m)
{
if
(!en[j])
count++; //只有之前没有访问过的才可以加入。
if
(count%k==0&&!en[j])
{
en[j]=1;
len--;
}
}
}
cout<<
"Selection #"
<<t<<endl;
int
time
=1;
for
(i=0;i<m;i++)
if
(!en[i]&&
time
==1)
{
cout<<i+1;
time
++;
}
else
if
(!en[i]&&
time
!=1)
cout<<
" "
<<i+1;
cout<<endl;
cout<<endl; //
这里要有两个空行,无聊的格式。
}
return
0;
}
这是第五篇了,约瑟夫问题我开始写的时候也是有点蒙,其实for()循环的i的作用只是保证环绕式循环通常i=(i+1)%m,真正计数作用的是count,真正的判断都是与count有关。 希望有点用吧。今天是18.6.26,距离放暑假还有1个月吧。