2013-08-26 60 views
1

這是一個來自SPOJ的問題WA in IITKWPCO SPOJ

小費魯達喜歡玩很多。如你所知,他只是玩數字。所以他給了n個數字。現在嘗試將數字分組爲不相交的集合,每個集合包含兩個數字。如果集合中的小數字恰好是大數的一半,他可以形成包含兩個數字的集合。

給定n個數字,找出他可以形成多少個最大數量的集合?

輸入

T:測試用例的數量。 (1 < = T < = 100)。

對於每個測試例:

第一行包含n個:(1 < = N < = 100)

然後下一行包含n個單個空間分隔。每個數字的範圍將介於1和10^6之間。

輸出

對於每個測試用例,輸出可以形成的最大數量的集合。

輸入:

輸出:

我的代碼::

#include <stdio.h> 
#include <math.h> 
#include <string.h> 

int main() 
{ 
    int t; 
    scanf("%d", &t); 

    while (t--) { 
      int n, i, j; 
      scanf("%d", &n); 
      long int arr[n], mini, maxi; 
      char str[105]; 

      for (i = 0;i < n;i++) { 
        str[i] = '0'; 
        scanf("%ld", &arr[i]); 
      } 

      for (i = 0;i < n;i++) { 
        for (j = 0;j < n;j++) { 
          mini = fmin(arr[i], arr[j]); 
          maxi = fmax(arr[i], arr[j]); 
          if ((maxi == 2 * mini) && (str[i] == '0' && str[j] == '0')) { 
            str[i] = str[j] = '1'; 
            break; 
          } 
        } 
      } 

      long int cnt = 0; 
      for (i = 0;i < n;i++) { 
        if (str[i] == '1') { 
          cnt++; 
        } 
      } 

      printf("%ld\n", cnt/2); 

    } 
    return 0; 
} 

有人可以PLZ指出我要去的地方錯誤或任何角落的測試情況下我是失蹤??

+0

你想做什麼,發生了什麼,你期望發生什麼? –

+0

我得到了正確的輸出爲所有的測試用例,我試過但仍然在SPOJ它評估爲錯誤ANSWER.I創建一個字符數組並初始化爲全'0',如果較低數字是更高數字的一半,然後我初始化該位置'1'。此後,我將在「str」中得到1的偶數。因此,我只是將計數減2,以獲得有問題的對的數量。 – rock321987

回答

1

你的邏輯存在缺陷。

考慮其中輸入數組是的情況下{2,4,1,8}

此答案應該是2中,由於集合可以形成{1,2}和{4,8} 。但是,對於這種情況,您的代碼將輸出1(它將將2與4配對,並且只能創建一個集合)。

我已經通過對數組進行排序來解決了這個問題,然後對每個元素檢查是否存在兩次該元素。如果是,則將其標記爲已使用並增加收集計數。

(僞代碼):

sort(array) 
count = 0; 
for(i=0;i<size;i++){ 
    if(used[i]) continue; //used elements should not be re-considered 
    for(j=i+1;j<size;j++){ 
    if(array[j]==2*array[i] && !used[j]){ 
     used[j] = true;. 
     count++; 
    } 
    } 
} 

可變計數現在將有集的最大可能數量。

注意尋找2 *陣列[I]數組中也可以通過二進制搜索來實現,但由於該陣列是非常小(尺寸< = 100)

這裏是我的 C++ code因爲那是不必要的問題。 (我已經使用C++標準庫進行排序,您可以使用您選擇的任何排序算法)。

希望這會有所幫助。 乾杯。

0
Check out this easy solution: 
#include<iostream> 
#include<algorithm> 
#include<stdio.h> 
using namespace std; 
int main() 
{ 
    int t=0; 
    scanf("%d",&t); 
    while(t>0) 
    { 
     t=t-1; 
     int num=0; 
     long long int n[10001]; 
     int count=0; 
     scanf("%d",&num); 
     for(int k=0;k<num;k++) 
     scanf("%lld",&n[k]); 
     sort(n,n+num); 
     for(int i=0;i<num;i++) 
     { 
      if(n[i]==-1)continue; 
      for(int j=i+1;j<num;j++) 
      { 
       if(n[j]==n[i]*2 &&n[i]!=-1 &&n[j]!=-1) 
       { 
        count=count+1; 
        n[i]=-1; 
        n[j]=-1; 
        break; 
        } 


       } 

      } 

     printf("%d\n",count); 

     } 




// getchar(); 
    return 0; 
    } 
+0

您還可以添加解釋嗎? – Robert

+0

如你所知,這個問題可以很容易地由bruteforce完成。 –

+0

首先我按遞增順序對數組進行排序,如果我選擇第一個元素並使用inner for循環檢查哪個元素滿足條件,如果我從外部循環中選擇第i個元素並檢查[j] = 2 * a [i];其中第j個元素是從內部循環中選擇的,現在將計數增加「1」,並將該元素標記爲[1],並且a [i] = - 1,a [j] = - 1可以使用下次如果狀態a [i] == - 1只是繼續,因爲它已經被用於設置。您也可以使用qsort,它會花費nlogn時間對數組進行排序。如果您仍然有疑問,請告訴我。 –