【问题标题】:Non Divisible subset in pythonpython中的不可分割子集
【发布时间】:2016-05-25 16:50:49
【问题描述】:

我得到了一个包含 n 个整数的集合 S,并且必须打印 S' 的最大子集 S' 的大小,其中 S' 中任意 2 个数字的总和不能被 k 整除。

输入格式

第一行包含 2 个以空格分隔的整数,分别为 n 和 k。 第二行包含 n 个以空格分隔的整数,描述集合的唯一值。

我的代码:

import sys


n,k = raw_input().strip().split(' ')
n,k = [int(n),int(k)]
a = map(int,raw_input().strip().split(' '))
count = 0


for i in range(len(a)):
    for j in range(len(a)):
        if (a[i]+a[j])%k != 0:
            count = count+1

print count

输入:

4 3
1 7 2 4

预期输出:

3

我的输出:

10

我做错了什么?有人吗?

【问题讨论】:

  • 您的代码做了一些与问题完全无关的事情。这不是你做错的一些小细节的问题。
  • @C14L:如果不选择两个加起来是 k 倍数的元素,你能选择 S 的多少个元素?
  • @user2357112 那么len([x for x in itertools.combinations(a, 2) if operator.add(*x) % k])呢?
  • @C14L:你还是在解决错误的问题。
  • @user2357112 我得到了正确的解决方案。并且没有剩余的项目[(1, 7), (1, 4), (7, 4)]可以被k整除。

标签: python


【解决方案1】:

您可以使用以下方法在O(n) 时间内解决它:

L = [0]*k

for x in a: 
    L[x % k] += 1
res = 0
for i in range(k//2+1):
    if i == 0 or k == i*2:
        res += bool(L[i])
    else:
        res += max(L[i], L[k-i])

print(res)

【讨论】:

  • 这是一个非常棒的答案,更深入地解释了这个算法:cs.stackexchange.com/questions/57873/…
  • 兄弟.. 这条线是什么意思? res += bool(L[i])
  • 如果L[i] 为“真”(非零),则增加res
  • @planetp,类似于 ruby​​ 中的!L[i].nil?
  • @Eswar // 表示下限,也就是先划分,然后向下取整。 3 / 2 = 1.5, 3 // 2 = 1
【解决方案2】:

是的,这个问题的 O(n) 解决方案非常有可能。就像planetp 正确指出的那样,它与我用java 编写的解决方案几乎相同。添加了 cmets 以便更好地理解。

导入 java.io.;导入 java.util.;

公共类解决方案{

public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    int n=in.nextInt();
    int k=in.nextInt();
    int [] arr = new int[k];
    Arrays.fill(arr, 0);
    Map<Integer,Integer> mp=new HashMap<>();

考虑到没有重复,将值存储在地图中。如果有重复,您可以将它们存储在数组列表中。只有这样你才会有不同的结果。 for(int i=0;i

    int res=0;

    for(int i=0;i<=(k/2);i++)
    {
        if(i==0 || k==i*2)
        {
            if(arr[i]!=0)
               res+=1;
        }

如果没有。能被 k 整除,我们只能有一个,如果 no 正好是 k 的一半,那么我们只能有 1。有理如果 a 和 b 可以被 k 整除,那么 a+b 也可以被 k 整除。同样,如果 c%k=k/2 那么如果我们有多个这样的否。它们的组合可以被 k 整除。因此,我们将它们分别限制为 1 个值。 别的 { int p=arr[i]; int q=arr[k-i]; 如果(p>=q) 水库+=p; 别的 资源+=q; }

如果 a[x]>a[k-x] 得到更大的值,这很容易从列表中的 0 到 k/2 的列表中找出哪个更大。即如果我们有 k=4 而我们没有。 1,3,5,7,9,13,17。那么 a[1]=4 和 a[3]=2 因此选择 a[1] 因为 1,5,13,​​17 可以保持在一起。

    }   
       System.out.println(res);
    }
}

【讨论】:

  • 如果你想存储值,我会使用 HashSet,而不是 Map
【解决方案3】:
# given k, n and a as per your input.
# Will return 0 directly if n == 1
def maxsize(k, n, a):
    import itertools
    while n > 1:
        sets = itertools.combinations(a, n)
        for set_ in sets:
            if all((u+v) % k for (u, v) in itertools.combinations(set_, 2)):
                return n
        n -= 1
    return 0

【讨论】:

  • 指数时间,但至少它通常给出正确的答案。不过,return 0 是错误的值。它只适用于 n=0。当输入至少有一个元素时,我们总是可以选择一个有效的 1 元素子集。
  • 是的。指数时间。你期待我打破 NP 集吗?付我 1000000 美元(CMI 奖),我会试试 XDDDD
  • 您无需求解 P/NP 即可在线性时间内完成此操作。有一个相当简单的解决方案,基于决定是否允许每个可能的x 在您的集合中使用残基xk-x,对于残基0k/2 有特殊情况。
  • 将其发布为答案并获得我的支持;)。我今天太笨了。
【解决方案4】:

Java 解决方案

public class Solution {

    static PrintStream out = System.out;

    public static void main(String[] args) {
        /* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
        Scanner in = new Scanner (System.in);
        int n = in.nextInt();
        int k = in.nextInt();        
        int[] A = new int[n];

        for(int i=0;i<n;i++){
            A[i]=in.nextInt();
        }

        int[] R = new int[k];
        for(int i=0;i<n;i++)            
            R[A[i] % k]+=1;

        int res=0;
        for(int i=0;i<k/2+1;i++){
            if(i==0 || k==i*2)
                res+= (R[i]!=0)?1:0;
            else
                res+= Math.max(R[i], R[k-i]);            
        }

        out.println(res);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 2015-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多