题目简介
一个活动有N个人参加,一个主持人和N-1个普通参加者,其中所有的人都认识主持人,主持人也认识所有的人,主持人要求N-1个参加者说出他们在参加者中所认识的人数,如果A认识B,则B认识A,所以每个参赛者最少是会认识一个人,就是主持人。输入每个参赛者所认识的人数后,需要判断他们中有没有人说谎。
input
第一行是N,N=0表示结束
第二行是N-1个数字 ,第n个数字表示第n个参赛者所认识的人的数目
Output
true或者false
input sample
7
1 2 4 5 5 3
9
3 7 7 7 7 5 6 6
output sample
false
true
解题思路
我们可以把每个参赛者认识的人用一个vectro<int> friendNum来保存。然后我们一个一个的判断第i个人有没有骗人。
我在这里说明一下friendNum的意义:friendNum[i]表示第i个人所认识的朋友的个数;friendNum.size()其实就是剩余参赛者的数目。(为什么说是剩余呢?因为可能有的参赛者一个人都不认识,同时当剩余的人为0时就是没人骗人)
那么,我们如何知道滴i个人没骗人呢?很简单如果friendNum[i] <= friendNum.size()-1就可以了(ps:这里的人就是指参赛者,主持人可以看做一个特殊的参赛者),如果第i个人没有骗人我们就将他从friendNum中移出去。同时将剩余的friendNum[i]个参赛者所认识的人的个数减1,因为可以假定他们都认识地i个参赛者。(为什么可以假定?这个。。我不好解释,你想不明白的话我也没办法了)
最后如果有人只认识一个人,减1以后就没用认识的人了也需要将其移出去。
源代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool cmp(int a, int b)
{
return a < b;
}
void eraseZero(vector<int> & v)
{
for(int i = 0; i < v.size(); i++)
{
if(v[i] == 0)
{
v.erase(v.begin()+i);
i--;
}
}
}
int main()
{
int n;
vector<int> friendNum; //每个人交的朋友数
while(cin >>n && n != 0 )
{
friendNum.clear();
int num;
for(int i = 0; i < n-1; i++) //主持人不接受数据
{
cin >> num;
friendNum.push_back(num);
}
friendNum.push_back(n-1); //将主持人也加以考虑
while(!friendNum.empty())
{
sort(friendNum.begin(),friendNum.end(),cmp);
int t = friendNum[friendNum.size()-1]; //取尾部也就是认识的人最多的数,判断其是否说假话
if(t <= friendNum.size()-1) //是真的
{
friendNum.pop_back();
int j = friendNum.size()-1,k = t;
while(t--)
{
friendNum[j--] -= 1;
}
}
else //他在骗人
{
break;
}
eraseZero(friendNum); //消除没有朋友了的人
}
if(friendNum.empty()) cout << "true" << endl;
else cout << "false" << endl;
}
return 0;
}