zoukankan      html  css  js  c++  java
  • POJ3750: 小孩报数问题+一道经典约瑟夫问题(猴子选大王)

    又一次因为一个小错误,POJ上Wrong Answer了无数次。。。。。

    在差不多要放弃的时候,发现了这个猥琐的不能再猥琐的bug,改完了提交就AC了,简直无语。。。。

    本题wo采用模拟方法:

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 struct child{
     6     char name[16];
     7     int id;
     8     //child(string, int);
     9 }cd[100];
    10 void init(int n){
    11     char s[16];
    12     for(int i=1;i<=n;i++){
    13         scanf("%s",cd[i].name);
    14         cd[i].id=0;
    15     }
    16 }
    17 int main(){
    18     int n,w,s; char c;
    19     scanf("%d",&n);
    20     init(n);
    21     scanf("%d%c%d",&w,&c,&s);
    22     cd[w].id=1;
    23     int pt=w;
    24     int kill=0;
    25     while(true){
    26         int step=s%(n-kill)-1;
    27         if(step<=0) step=step+n-kill;
    28         /*
    29             这里的取模运算是考虑到s值可能非常大,如果这样的话,模拟报数过程1。。。。s将会非常
    30             耗时间。
    31             至于为什么这么取模,自己算一算就明白了。 
    32         */
    33         for(int i=1;i<=step;i++){
    34                 int ptr=pt%n+1;
    35                 while(cd[ptr].id==-1){//要跳过已经被kill的元素 
    36                     ptr=ptr%n+1;
    37                 }
    38                 cd[ptr].id=cd[pt].id+1;
    39                 pt=ptr;
    40         }//这里的pt指向的就是我们要删除的元素 
    41         cd[pt].id=-1;//将id赋值为-1,相当于删除动作 
    42         printf("%s
    ",cd[pt].name);
    43         kill++;
    44         if(kill==n) break; //已经清空,跳出循环 
    45         int ptr=pt%n+1;
    46         while(cd[ptr].id==-1){
    47                     ptr=ptr%n+1;
    48         }
    49         cd[ptr].id=1;
    50         pt=ptr;
    51             
    52     }
    53     //system("pause");
    54     return 0;
    55 }
    View Code

    还有可以用双向循环链表来模拟:

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 using namespace std;
     5 struct node{
     6     int id;
     7     node *next,*pre;
     8     node();
     9     node(int);
    10 };
    11 node *head;
    12 char name[101][20];
    13 node::node(int value){
    14     id=value;
    15     next=pre=NULL;
    16 }
    17 void build(int n){
    18     head=new node(1);
    19     head->next=head->pre=head;
    20     if(n==1) return;
    21     node *p=head;
    22     for(int i=2;i<=n;i++){
    23         node *a=new node(i);
    24         p->next=a;
    25         a->pre=p;
    26         p=a;        
    27     }
    28     p->next=head;
    29     head->pre=p;
    30 }
    31 void print(){
    32     node *p=head;
    33     printf("%d ",p->id);
    34     p=p->next;
    35     while(p!=head){
    36         printf("%d ",p->id);
    37         p=p->next;
    38     }
    39     printf("
    ");
    40 }
    41 void joseph(int s,int k){
    42     node *p=head;
    43     s--;
    44     while(s--) p=p->next;
    45     while(p->next!=p){
    46         for(int i=1;i<=k-1;i++) p=p->next;
    47         printf("%s
    ",name[p->id]);
    48         node *front=p->pre;
    49         node *rear=p->next;
    50         p=rear;
    51         front->next=rear;
    52         rear->pre=front;        
    53     }
    54     printf("%s
    ",name[p->id]);
    55 }
    56 int main(){
    57     int n; char c;
    58     scanf("%d",&n);
    59         build(n);
    60         //print();
    61         for(int i=1;i<=n;i++){
    62             scanf("%s",name[i]);
    63         }
    64         int s,k;
    65         scanf("%d%c%d",&s,&c,&k);
    66         joseph(s,k);
    67 }
    View Code

    猴子选大王问题: 

    题目描述约瑟夫问题:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。

    输入每行是用空格分开的两个整数,第一个是 n, 第二个是 m ( 0 < m,n <=300)。最后一行是:

    0 0

    输出对于每行输入数据(最后一行除外),输出数据也是一行,即最后猴王的编号
    样例输入

    6 2
    12 4
    8 3
    0 0

    样例输出

    5
    1
    7
     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 struct child{
     6     int name;
     7     int id;
     8     //child(string, int);
     9 }cd[100];
    10 void init(int n){
    11     for(int i=1;i<=n;i++){
    12         cd[i].name=i;
    13         cd[i].id=0;
    14     }
    15 }
    16 void solve(int n,int s){
    17     init(n);
    18     cd[1].id=1;
    19     int pt=1;
    20     int kill=0;
    21     while(true){
    22         int step=s%(n-kill)-1;
    23         if(step<=0) step=step+n-kill;
    24         /*
    25             这里的取模运算是考虑到s值可能非常大,如果这样的话,模拟报数过程1。。。。s将会非常
    26             耗时间。
    27             至于为什么这么取模,自己算一算就明白了。 
    28         */
    29         for(int i=1;i<=step;i++){
    30                 int ptr=pt%n+1;
    31                 while(cd[ptr].id==-1){//要跳过已经被kill的元素 
    32                     ptr=ptr%n+1;
    33                 }
    34                 cd[ptr].id=cd[pt].id+1;
    35                 pt=ptr;
    36         }//这里的pt指向的就是我们要删除的元素 
    37         cd[pt].id=-1;//将id赋值为-1,相当于删除动作 
    38         kill++;
    39         if(kill==n){
    40             printf("%d
    ",cd[pt].name); break; //已经清空,跳出循环 
    41         }
    42         int ptr=pt%n+1;
    43         while(cd[ptr].id==-1){
    44                     ptr=ptr%n+1;
    45         }
    46         cd[ptr].id=1;
    47         pt=ptr;
    48             
    49     }
    50 }
    51 int main(){
    52          int n,s;
    53         while(scanf("%d%d",&n,&s)!=EOF&&n&&s){
    54             solve(n,s);
    55         }
    56         return 0;    
    57 }
    View Code

     

     
  • 相关阅读:
    关于字符编码
    cocosbuilder中使用字体描边时,字符重叠,间距过小问题
    2dx关于js响应layer触摸消息的bug
    关于js-binding中Layer触摸事件的优化
    2dx解析cocosbuilder中使用layer时的缺陷
    关于 2dx v3.7 UIScale9Sprite的bug
    c++11 Chrono时间库
    cocos2d-x lua table数据存储
    cocos2d-x lua 使用ListView
    Oracle数据库impdp时ora-00439:未启用功能:Deferred Segment Creation
  • 原文地址:https://www.cnblogs.com/fu11211129/p/4194343.html
Copyright © 2011-2022 走看看