1384:珍珠(bead)
時間限制: 1000 ms 內存限制: 65536 KB
提交數: 2039 通過數: 1061
【題目描述】
有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
思路:
根據Floyd原理可以求解:重量:A>B且B>C則A>C。題意要輸出不可能是中間重量的珍珠,假設A重量爲中間重量,則他前面就會有(n+1)/2-1個珍珠,後面也會有(n+1)/2-1個珍珠。所以不在中間重量的珍珠必有比他重超過(含等於) (n+1)/2或者比他輕超過(含等於) (n+1)/2的珍珠個數。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 110;
int a[N][N];
int b[N][N];
int num1[N];
int num2[N];
int n,m;
int main(){
scanf("%d %d",&n,&m);
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(num1,0,sizeof(num1));
memset(num2,0,sizeof(num2));
int x, y;
for(int i = 0; i < m;i++)
{
cin >> x >> y;
a[x][y] = 1;//x比y重
b[y][x] = 1;//y比x輕
}
for(int k = 1; k <= n; k++){
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++)
{
a[i][j] = a[i][j] ||(a[i][k] + a[k][j] == 2);//若i比k重且k比j重a[i][k]==1&&a[k][j]==1 相加等於2 說明2個都必需是1
b[i] [j] = b[i][j] ||(b[i][k] + b[k][j] == 2);//若i比k重且k比j輕
}
}
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
if(i != j){
if(a[i][j]) num1[i]++;//統計比i重的個數
if(b[i][j]) num2[i]++;//統計比i輕的個數
}
}
}
int ans = 0;
for(int i = 1; i <= n; i++){
if(num1[i] >= (n+1)/2 || num2[i] >= (n+1)/2)//只要二者有一個滿足,那這顆珍珠都不能爲中間重量的珍珠
ans++;
}
printf("%d\n",ans);
return 0;
}