poj2886 Who Gets the Most Candies?

poj2886 Who Gets the Most Candies?

这道题题意对于一般的ACMER应该不是什么问题吧!

首先是个约瑟夫问题的升级版

1).告诉你第一次是顺时针第k个人出队

2).某个人(编号为 i) 出队后,下个出队的是从这个开始查第num[i]个人,若num[i]<0,为逆时针数,否则顺时针数。

3).重复步骤2).,直到全部出队。

4).输出出队序号中,那个序号的约数最多的那个人名及约数个数。

这里需要知道一个知识:反素数。

详见http://www.cnblogs.com/shen1000/archive/2012/07/29/2613877.html

有了反素数,我们就知道那个序号为最终答案了。

怎么求出那个序号是谁呢?对于这个,目前我只知道用模拟来找出。

思路:每次找出第几个需要要出队的人得位置,然后根据位置,找到下个需要出队的位置。
线段树功能:update:出队一个人,以及找到出队人的下标。 query:找出出对人的左边有多少未出队的人。

详见代码:

View Code
  1 #include<iostream>
  2 #include<string>
  3 #include<queue>
  4 #include<map>
  5 #include<cmath>
  6 #include<stack>
  7 #include<algorithm>
  8 using namespace std;
  9 const int maxn = 500555;
 10 char name[maxn][12];
 11 int num[maxn];
 12 int rprim[35][2] = {
 13     498960,200,332640,192,277200,180,221760,168,166320,160,
 14     110880,144,83160,128,55440,120,50400,108,45360,100,
 15     27720,96,25200,90,20160,84,15120,80,10080,72,
 16     7560,64,5040,60,2520,48,1680,40,1260,36,
 17     840,32,720,30,360,24,240,20,180,18,
 18     120,16,60,12,48,10,36,9,24,8,
 19     12,6,6,4,4,3,2,2,1,1};
 20 
 21 //1.bulid();
 22 //2.query(a,b)
 23 //3.update(a,b)
 24 #define lson l , m , rt << 1
 25 #define rson m + 1 , r , rt << 1 | 1
 26 
 27 int sum[maxn<<2];
 28 int n,k;
 29 //根据题意做相关修改,询问时的操作 
 30 int operate(int a,int b){
 31     return a+b;
 32 }
 33 void PushUp(int rt){
 34     sum[rt]=operate(sum[rt<<1],sum[rt<<1|1]);
 35 }
 36 void bulid(int l=1,int r=n,int rt=1){
 37     if(l==r){// 据题意做相关修改
 38         sum[rt]=1;return ;
 39     }
 40     int m=(l+r)>>1;
 41     bulid(lson);
 42     bulid(rson);
 43     PushUp(rt);
 44 }
 45 void update(int p,int add=0,int l=1,int r=n,int rt=1){
 46     if(l==r){// 据题意做相关修改
 47         sum[rt]=add;k=l;
 48         //printf("k=%d\n",k);
 49         return ;
 50     }
 51     int m=(l+r)>>1;
 52     if(p<=sum[rt<<1])update(p,add,lson);
 53     else update(p-sum[rt<<1],add,rson);
 54     PushUp(rt);
 55 }
 56 
 57 int query(int L,int R,int l=1,int r=n,int rt=1){
 58     if(L<=l && r<=R){
 59         return sum[rt];
 60     }
 61     int m=(l+r)>>1;
 62     int ret=0;
 63     if(L<=m)ret=operate(ret,query(L,R,lson));
 64     if(R> m)ret=operate(ret,query(L,R,rson));
 65     return ret;
 66 }
 67 
 68 int main(){
 69     int p,x,now,leftnum,rightnum,m;
 70     while(~scanf("%d%d",&n,&k)){
 71         p=0;
 72         while(n<rprim[p][0])p++;
 73         x=rprim[p][0];
 74         bulid();
 75         //printf("sum[1]=%d\n",sum[1]);
 76         for(int i=1;i<=n;i++){
 77             scanf("%s%d",name[i],&num[i]);
 78         }
 79         m=n;
 80         now=k;
 81         //printf("x=%d\n",x);
 82         for(int i=1;i<x;i++){
 83             update(now);//now出队 
 84             m--;
 85             //printf("m=%d\n",m);
 86             //转化为向左查多少人 
 87             if(num[k]%m==0){
 88                 if(num[k]>0)num[k]=m;
 89                 else num[k]=1;
 90             }else{
 91                 num[k]%=m;
 92                 if(num[k]<0)num[k]+=m+1;
 93             }
 94             leftnum=query(1,k);//找出now左边有多少个人 
 95             rightnum=m-leftnum;
 96             //printf("num[%d]=%d left=%d  right=%d\n",k,num[k],leftnum,rightnum);
 97             if(num[k]<=rightnum){
 98                 now=leftnum+num[k];
 99             }else{
100                 now=num[k]-rightnum;
101             }
102         }
103         update(now);
104         printf("%s %d\n",name[k],rprim[p][1]);
105         
106     }
107     
108     return 0;
109 }
110 /*
111 4 1
112 Tom 2
113 Jack 4
114 Mary -1
115 Sam 1
116 */
Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值