算法竞赛入门经典(第2版)第4章 函数和递归
例题4-3 救济金发放 UVa133
感悟。
1、阅读书中题目,从网站下载英文原题,重点在看输出数据与格式。
2、首先想到设置标签book[100],《啊哈!算法》中学来的。
3、一开始准备逆时针,顺时针,同时处理,发现两种情况数过的人数不一样的。
4、因此,先处理逆时针,再处理顺时针,写着写着,觉得处理手法挺像快速排序的,几种排序(冒泡排序,选择排序,插入排序,快速排序)要熟练掌握啊。
5、写好,马上测试数据,没通过,马上修改,再测试,测试数据通过,提交AC,挺顺利的。
6、约瑟夫问题加强版。
附上代码
环境Dev-cpp4.9.9.2
#include <stdio.h>
#include <string.h>
int book[100];//领过的标记1,没领过的标记0
int main(){
int n,k,m;
int kcount,mcount;
int ki,mi;
int kout,mout;
int first;
int ncount;
while(scanf("%d%d%d",&n,&k,&m)==3&&n&&k&&m){
memset(book,0,sizeof(book));
ncount=0;
ki=0;
mi=n+1;
first=1;
while(ncount!=n){//n个人全被处理完毕//处理手法有些类似快速排序
kcount=0;
mcount=0;
while(kcount!=k){//k系列处理
ki++;
if(ki>n)//ki越界处理
ki=1;
if(book[ki]==0)//未被选中计数 ki为当前值
kcount++;
}
while(mcount!=m){//m系列处理
mi--;
if(mi<1)//mi越界处理
mi=n;
if(book[mi]==0)//未被选中计数 mi为当前值
mcount++;
}
book[ki]=1;//不用担心ki==mi
book[mi]=1;
if(first){//打印处理
first=0;
if(ki!=mi){
printf("%3d%3d",ki,mi);
ncount+=2;
}
else{
printf("%3d",ki);
ncount++;
}
}else{
if(ki!=mi){
printf(",%3d%3d",ki,mi);
ncount+=2;
}
else{
printf(",%3d",ki);
ncount++;
}
}
}
printf("\n");
}
return 0;
}