WA在IITKWPCO SPOJ

时间:2013-08-26 17:25:15

标签: c

这是来自SPOJ

的问题 小费卢达很喜欢玩。如你所知他只玩数字。所以给他n个数字。现在尝试将数字分组为不相交的集合,每个集合包含两个数字。如果集合中的小数字恰好是大数字的一半,他可以形成包含两个数字的集合。

给出n个数字,找出他可以形成多少个最大数量的集合?

输入

T:测试用例数。 (1 <= T <= 100)。

对于每个测试用例:

第一行将包含n:(1&lt; = n&lt; = 100)

然后下一行将包含n个单独的空格分隔。每个数字的范围将介于1到10 ^ 6之间。

输出

对于每个测试用例,输出可以形成的最大集合数。

实施例

  

输入:

     

2

     

2

     

1 2

     

3

     

1 2 4

     

输出:

     

1

     

1

我的代码::

#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;
 }

有人可以指出我出错的地方或我错过的任何角落测试案例吗?

2 个答案:

答案 0 :(得分: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++;
     }
  }
}

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++; } } } 变量 count 现在将具有最大可能的集合数。

请注意,在数组中搜索2 * array [i]也可以通过二进制搜索来实现,但这是不必要的,因为数组非常小(大小<= 100)

这是问题的 C++ code 。 (我使用了c ++标准库进行排序,你可以使用你选择的任何排序算法。)

希望这会有所帮助。 欢呼声。

答案 1 :(得分: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;
    }