找小水王
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 编程、修改、测试、撰写博客