找小水王

1、题目要求:

  在一个论坛中,有三个用户,他们的发帖量在总帖数中占了1/4 以上,并且在每一个帖子下都有他们的回复,人们管他叫小水王 

  用最简单、快速的方法找到这三个小水王

2、实现思路:

  在上一次找大水王的基础上,这次的思路就比较清晰了。

  同样的,这样想,一共100个帖子,三个水王的数量num[0]、num[1]、num2[]大于25,其余的所有id发帖总数other加在一起也不够25,只要每四个不同的id个数同时减一,最终每一个king的num 会减other次,剩下的三个就是水王的id

  num=当前king多出来的个数(即消剩下的个数)+当前king被减去的个数[即(总数-剩下的总个数)/4]

3、思路整理(实现步骤):

     不需要真正对列表进行删除相消(前提:这个列表中必须有一个符合条件的水王)

     从第一个id开始

       如果king列表中已存在当前Id,将对应的num【】加一,说明,当前 Id又多了一个帖子;

       如果king列表中还没有当前id,找到king列表里的空位置(即定义的“0”),将空位替换为当前Id,并将对应的num加一,说明,当前Id 被假设为一个king;

       如果,king列表既没当前id,又没空位置,将每一个king对应的num减一,跳过此id,进行下一个id判断,即消去四个不同的id

    循环至最后一个id

4、源代码:

 1 //找水王(在一个论坛中,发帖数超过总帖数的四分之一的那三个id号)假设,没人用“0”作为Id
 2 //王永维,2016,05,23
 3 #include<iostream>
 4 #include<string>
 5 #define N 30     //可以定义列表长度
 6 using namespace std;
 7 
 8 int main()
 9 {
10     //定义三个水王
11     string king[3]={"0","0","0"};
12     //定义三个水王比其他 id 多发帖的次数
13     int num[3]={0,0,0};
14     //定义列表
15     string IdList[N]={"2水货","3潜水员","1水王","3潜水员","1水王","2水货","3潜水员","1水王","3潜水员","1水王","2水货","www","1水王","2水货","3潜水员","2水货","www","1水王","2水货","3潜水员","2水货","3潜水员","1水王","3潜水员","1水王","2水货","www","www","2水货","3潜水员"};
16 
17     //一次遍历,找出三个小水王,即 king【1,2,3】
18     for(int i=0;i<N;i++)
19     {
20         //如果king列表中已存在当前Id,将对应的num【】加一
21         if(king[0]==IdList[i])
22         {
23             num[0]++;
24         }
25         else if(king[1]==IdList[i])
26         {
27             num[1]++;
28         }
29         else if(king[2]==IdList[i])
30         {
31             num[2]++;
32         }
33         //如果king列表中还没有当前id,找到king列表里的空位置(即定义的“0”),将空位替换为当前Id,并将对应的num加一
34         else if(num[0]==0)
35         {
36             king[0]=IdList[i];
37             num[0]++;
38         }
39         else if(num[1]==0)
40         {
41             king[1]=IdList[i];
42             num[1]++;
43         }
44         else if(num[2]==0)
45         {
46             king[2]=IdList[i];
47             num[2]++;
48         }
49         //如果,king列表既没当前id,又没空位置,将每一个king对应的num减一,跳过此id,进行下一个id判断
50         //次操作相当于消去四个不同Id
51         else
52         {
53             num[0]--;
54             num[1]--;
55             num[2]--;
56         }
57     }
58     //num是比其他的id多出来的,而其他的id总数是N-num[0]-num[1]-num[2]
59     //平均下来每个king 的num 减了1/4
60     int other=(N-num[0]-num[1]-num[2])/4;
61     num[0]=other+num[0];
62     num[1]=other+num[1];
63     num[2]=other+num[2];
64     cout<<"三个水王 id 分别是:"<<endl;
65     cout<<"\t"<<king[0]<<"\t"<<king[1]<<"\t"<<king[2]<<endl;
66     cout<<"三个水王发帖数分别是:"<<endl;
67     cout<<"\t"<<num[0]<<"\t"<<num[1]<<"\t"<<num[2]<<endl;
68     return 0;
69 }

5、运行结果:

测试列表   string IdList[N]={"2水货","3潜水员","1水王","3潜水员","1水王","2水货","3潜水员","1水王","3潜水员","1水王","2水货","www","1水王","2水货","3潜水员","2水货","www","1水王","2水货","3潜水员","2水货","3潜水员","1水王","3潜水员","1水王","2水货","www","www","2水货","3潜水员"};

测试列表

   string IdList[N]={"tt55","eee","ott","oottt","eee","eee","oottt","tt55","tt55","oottt"};

6、总结分析:

   这次的问题是在上一次的思路基础上做的,但比我预期时间多花了许多时间,因为这次的是3个水王,我最开始是这样写的,

for(int i=0;i<N;i++){for(int j=0;i<3;i++){if(king[j]==IfList[i]){……}……}

我的想法是,既然三个水王,可以用king【】数组和num【】数组,将当前 id与已有的king【】,num【】进行比较,但问题是,在进行这个i<3的循环里边需要进行判断,在循环外边也需要判断!!!而且,外边和里边的循环如果附合判断,就不需要进行下边的判断了,

    需要一个break??不对,需要一个continue??也不对!!!

    这个真的是把我弄崩溃了。。。

    偶然发现,如果不用循环,这个问题就简单多了,大不了多敲几次判断语句。最终的结果就出来了!

项目日志:

2016、5、23    17:00-18:00    19:10-21:30    约200min    编程

2016、5、27    9:00-11:30                约120min    编程、修改、测试、撰写博客

posted @ 2016-05-27 11:29  David~Wang  阅读(205)  评论(0编辑  收藏  举报