【Floyd】珍珠
【题目描述】
有n颗形状和大小都一致的珍珠,它们的重量都不相同。n为整数,所有的珍珠从1到n编号。你的任务是发现哪颗珍珠的重量刚好处于正中间,即在所有珍珠的重量中,该珍珠的重量列(n+1)/2位。下面给出将一对珍珠进行比较的办法:
给你一架天平用来比较珍珠的重量,我们可以比出两个珍珠哪个更重一些,在作出一系列的比较后,我们可以将某些肯定不具备中间重量的珍珠拿走。
例如,下列给出对5颗珍珠进行四次比较的情况:
1、珍珠2比珍珠1重
2、珍珠4比珍珠3重
3、珍珠5比珍珠1重
4、珍珠4比珍珠2重
根据以上结果,虽然我们不能精确地找出哪个珍珠具有中间重量,但我们可以肯定珍珠1和珍珠4不可能具有中间重量,因为珍珠2、4、5比珍珠1重,而珍珠1、2、3比珍珠4轻,所以我们可以移走这两颗珍珠。
写一个程序统计出共有多少颗珍珠肯定不会是中间重量。
【输入】
第一行包含两个用空格隔开的整数N和M,其中1≤N≤99,且N为奇数,M表示对珍珠进行的比较次数,接下来的M行每行包含两个用空格隔开的整数x和y,表示珍珠x比珍珠y重。
【输出】
一行包含一个整数,表示不可能是中间重量的珍珠的总数。
【样例输入】
5 4 2 1 4 3 5 1 4 2
【样例输出】
2
看完题目没思路?其实超简单
弗洛伊德轻松搞定!!!
其实如果有(n+1)/2个珍珠比一个珍珠重,那么这个珍珠一定不在中间。
AC代码如下
1 #include<iostream> 2 #include<cstring> 3 #include<string> 4 #include<cstdio> 5 #define N 1001 6 using namespace std; 7 int heavy[N][N], light[N][N]; 8 int n, m, ans=0; 9 int main() 10 { 11 cin>>n>>m; 12 int a, b; 13 for (int i=1; i<=m; i++){ 14 cin>>a>>b; 15 heavy[a][b]=1; 16 light[b][a]=1; 17 } 18 for (int k=1; k<=n; k++) 19 for (int i=1; i<=n; i++) 20 for (int j=1; j<=n; j++) 21 if(i!=j && i!=k && j!=k){ 22 heavy[i][j]=heavy[i][j] || (heavy[i][k] && heavy[k][j]); //如果i比k重且k比j重,那么i比j重 23 light[i][j]=light[i][j] || (light[i][k] && light[k][j]); 24 } 25 for (int i=1; i<=n; i++){ 26 a=0;b=0; 27 for(int j=1; j<=n; j++){ 28 if(heavy[i][j]) 29 a++; 30 else if(light[i][j]) 31 b++; 32 } 33 if(a>=(n+1)/2 || b>=(n+1)/2) ans++; 34 } 35 cout<<ans<<endl; 36 return 0; 37 }
![](https://img2018.cnblogs.com/blog/1551379/201905/1551379-20190518094636158-652789969.jpg)