问题描述
近日,信竞班有人在散布谣言,说老板体重超重 ,这有损老板在同学们心中的完美形象,让老板很是头疼。老板还了解到,散布该谣言的人号称自己拥有最合适的体重,体重值位于所有人的正中间,老板决心找出这个家伙。
信竞班有n名同学,编号1到n,已知每名同学的体重都不相同。老板想知道,哪个同学的体重位于正中间。也就是如果将n名同学按体重由轻到重排序后,该名同学位于第(n+1)/2名,这名同学一定是谣言散布者。
但是同学们都不肯准确告诉老板他的体重,老板只好在暗中收集信息。
例如:n=5时,老板搜集到了如下信息:
1号同学比2号同学轻
3号同学比4号同学轻
1号同学比5号同学轻
2号同学比4号同学轻
根据上面的情报,虽然老板不能准确得出哪个同学具有中间体重,但他可以肯定4号和1号不可能具有中间体重,因为,1、2、3比4轻,而2、4、5比1重,所以他可以排除到这两名同学。
写一个程序统计出目前我们最多能排除掉多少个同学。也就是确定有多少个同学肯定不会是中间体重。
输入格式
第一行:两个整数n和m,其中n为奇数表示学生总数,m表示何老板搜集到的信息条数。
接下来的m行,每行两个整数x和y,表示x号同学比y号同学重。
输出格式
若干个整数,按从小到大的顺序输出不可能是中间重量的学生的编号。
若一个也找不出来,输出0。
样例输入 1
5 4
2 1
4 3
5 1
4 2
样例输出 1
1 4
样例输入 2
11 5
1 2
3 4
5 6
7 8
9 10
样例输出 2
0
样例输入 3
31 29
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
10 1
11 1
12 1
13 1
14 1
15 1
16 1
17 1
18 1
19 1
20 1
21 1
22 1
23 1
24 1
25 1
26 1
27 1
28 1
29 1
30 1
样例输出 3
1
提示
1<=n<=100
1<=m<=5000
——————————————————————————————————
解:
/*
对于任意一个人i,我们需要算出比他轻的总人数light[i]和比他重的总人数heavy[i]。
若能够确定比i轻或比i重的人数>=(n+1)/2 ,那么可以确定此人一定不是中间体重
怎样统计出比i轻和比i重的总人数呢?
我们通过floyd就可以推导出任意两人之间的轻重关系
*/
#include<iostream>
#include<cstdio>
using namespace std;
//zhong[x][y]为true,表示x比y重; qing[x][y]为true,表示x比y轻。
bool zhong[100][100],qing[100][100];
int heavy[100],light[100];
//heavy[i]记录比i轻的同学个数; light[i]记录比重的同学个数。
int main()
{
//freopen("data10.in","r",stdin);
//freopen("data10.out","w",stdout);
int n,m,i,j,k,x,y,ans=0;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
zhong[x][y]=true;
qing[y][x]=true;
}
//floyd
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
if(zhong[i][k] && zhong[k][j])zhong[i][j]=true;
if(qing[i][k] && qing[k][j])qing[i][j]=true;
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
if(zhong[i][j])heavy[i]++;
if(qing[i][j])light[i]++;
}
bool flag=false;
for(i=1;i<=n;i++)
if(heavy[i]>=(n+1)/2 || light[i]>=(n+1)/2)
{
flag=true;
cout<<i<<" ";
}
if(flag==false)cout<<0;
return 0;
}
本人代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,s,x,a[101]= {},c[101]= {};
bool b[101][101]= {},f,d[101][101]= {};
int main()
{
cin>>n>>m;
for(int i=1; i<=m; i++)
{
cin>>s>>x;
if(b[s][x]==0)
{
b[s][x]=1;
d[x][s]=1;
a[s]++;
c[x]++;
}
for(int i=1; i<=n; i++)
{
if(b[x][i]==1&&b[s][i]==0)
{
b[s][i]=1;
a[s]++;
}
if(d[i][x]==1&&d[i][s]==0)
{
d[i][s]=1;
c[i]++;
}
}
}
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
for(int k=1; k<=n; k++)
{
if(b[i][j]==1&&b[j][k]==1&&b[i][k]==0)
{
b[i][k]=1;
a[i]++;
}
if(d[j][i]==1&&d[i][k]==1&&d[j][k]==0)
{
d[j][k]=1;
c[j]++;
}
}
}
}
for(int i=1; i<=n; i++)
{
if(a[i]>n/2)
{
cout<<i<<" ";
f=1;
}
if(c[i]>n/2)
{
cout<<i<<" ";
f=1;
}
}
if(f==0)
{
cout<<"0";
}
return 0;
}