কোনও মাস্কের সেটের সাথে মিলে যায় ভারসাম্য বাইনারি স্ট্রিংগুলি গণনা করুন


10

একটি বাইনারি স্ট্রিং একটি স্ট্রিং যা শুধুমাত্র থেকে টানা অক্ষর রয়েছে 01 । একটি ভারসাম্য বাইনারি স্ট্রিং একটি বাইনারি স্ট্রিং যা হ'ল 0 এস হিসাবে 1 এস থাকে।

আপনাকে একটি ইতিবাচক পূর্ণসংখ্যা এন এবং মাস্কগুলির একটি স্বেচ্ছাসেবী সংখ্যা দেওয়া হবে, যার প্রতিটিই 2n অক্ষর দীর্ঘ এবং এতে কেবলমাত্র 012 থেকে আঁকা অক্ষর রয়েছে । একটি বাইনারি স্ট্রিং এবং একটি মাস্ক মিল যদি এটির দৈর্ঘ্য একই হয় এবং প্রতিটি অবস্থানে যেখানে মুখোশের সাথে 2 থাকে না সেখানে চরিত্রের সাথে একমত হয় । উদাহরণস্বরূপ মাস্ক 011022 বাইনারি স্ট্রিংগুলির সাথে মেলে 011000 , 011001 , 011010 , 011011

এন এবং মাস্কগুলি ইনপুট হিসাবে দেওয়া হয়েছে (নিউলাইন দ্বারা পৃথক), আপনাকে অবশ্যই স্বতন্ত্র সুষম বাইনারি স্ট্রিংগুলির সংখ্যা আউটপুট করতে হবে যা এক বা একাধিক মুখোশের সাথে মেলে।

উদাহরণ

ইনপুট

3
111222
000112
122020
122210
102120

যুক্তি

  • শুধুমাত্র সুষম বাইনারি মিলে স্ট্রিং 111222 হয় 111000
  • একমাত্র ভারসাম্য বাইনারি স্ট্রিংটি 000112 হল 000111
  • 122020 এর সাথে মিলে যাওয়া ভারসাম্যযুক্ত বাইনারি স্ট্রিংগুলি 111000 (ইতিমধ্যে গণনা করা হয়েছে), 110010 এবং 101010
  • সুষম বাইনারি মিলে স্ট্রিং 122210 হয় 110010 (ইতিমধ্যে সংখ্যাত), 101010 (ইতিমধ্যে সংখ্যাত) এবং 100110
  • 102120 এর সাথে মিলে যাওয়া ভারসাম্যযুক্ত বাইনারি স্ট্রিংগুলি 101100 এবং 100110 (ইতিমধ্যে গণনা করা হয়েছে)।

সুতরাং আউটপুট হওয়া উচিত

6

ইনপুট

10
22222222222222222222

যুক্তি

  • আছে 20 10 চয়ন দৈর্ঘ্য 20 সুষম বাইনারি স্ট্রিং।

আউটপুট

184756

বিজয়ী

বিজয়ী হবেন এমন একজন যা প্রতিযোগিতার ইনপুটটিকে দ্রুততম গণনা করে, অবশ্যই একে অন্যরকম ইনপুট হিসাবে একইভাবে চিকিত্সা করে। (আমি একটি স্পষ্ট বিজয়ী পেতে এবং বিভিন্ন ইনপুটগুলি বিভিন্ন বিজয়ী দেবে এমন ক্ষেত্রে এড়াতে আমি একটি নির্ধারিত কোড ব্যবহার করি you আপনি যদি দ্রুততম কোডটি খুঁজে পাওয়ার আরও ভাল উপায়ের কথা মনে করেন তবে আমাকে তাই বলুন)।

প্রতিযোগিতা ইনপুট

http://pastebin.com/2Dg7gbfV


2
এছাড়াও, আমি ব্যক্তিগতভাবে পেস্টবিনের চেয়ে আরও বেশি পছন্দ করি gist.github.com , নন্দনতত্ব এবং ভবিষ্যতের ত্রুটি উভয় জন্য।
orlp

3
@ অ্যালবার্টম্যাসক্লানস আমি মনে করি আপনার ইনপুট পরিবর্তন করার অধিকার সংরক্ষণ করা উচিত। অন্যথায়, কেউ আউটপুট হার্ডকোড করতে পারে।
mbomb007

1
আপনি যদি প্রত্যাশিত ফলাফল, এবং ব্যাখ্যা সহ প্রশ্নটিতে একটি ছোট্ট উদাহরণ পোস্ট করতে পারেন তবে এটি কার্যকর হবে। আমি কেবল ধীর হতে পারি, তবে আমি সংজ্ঞাটি পাই না। সুতরাং উদাহরণস্বরূপ, এন = 30 থেকে, আমরা কোনও সারিতে 30 0 বা 30 1 (2 ওয়াইল্ডকার্ড সহ) এর সিকোয়েন্সগুলি খুঁজছি? এই ক্রমগুলি কি ওভারল্যাপ করতে পারে? উদাহরণস্বরূপ, যদি আমি 32 1s এর সিকোয়েন্সটি পাই, তবে এটি 3 সিকোয়েন্স বা একক অনুক্রম হিসাবে গণনা করে? আমি যদি 60 1s (পুরো সারি) এর অনুক্রম পাই? এটি কি 1 সিকোয়েন্স, 2 সিকোয়েন্স বা 31 সিকোয়েন্স?
রেটো কোরাডি

3
সুতরাং আপনি এই ম্যাট্রিক্সে অনন্য অ্যারের সংখ্যার জন্য জিজ্ঞাসা করছেন যার সমান সংখ্যার 1 এবং 0 এর সমান আছে?
ASCIIThenANSI

1
দয়া করে আমাদের আরও কিছু পরীক্ষার ডেটা পাওয়া যাবে?
আলেকজান্ডার-ব্রেট

উত্তর:


2

সি

আপনি যদি লিনাক্সে না থাকেন, বা অন্যথায় সংকলন করতে সমস্যা হয় তবে আপনার সম্ভবত টাইমিং কোডটি মুছে ফেলা উচিত clock_gettime

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

long int binomial(int n, int m) {
  if(m > n/2) {
    m = n - m;
  }
  int i;
  long int result = 1;
  for(i = 0; i < m; i++) {
    result *= n - i;
    result /= i + 1;
  }
  return result;
}

typedef struct isct {
  char *mask;
  int p_len;
  int *p;
} isct;

long int mask_intersect(char *mask1, char *mask2, char *mask_dest, int n) {

  int zero_count = 0;
  int any_count = 0;
  int i;
  for(i = 0; i < n; i++) {
    if(mask1[i] == '2') {
      mask_dest[i] = mask2[i];
    } else if (mask2[i] == '2') {
      mask_dest[i] = mask1[i];
    } else if (mask1[i] == mask2[i]) {
      mask_dest[i] = mask1[i];
    } else {
      return 0;
    }
    if(mask_dest[i] == '2') {
      any_count++;
    } else if (mask_dest[i] == '0') {
      zero_count++;
    }
  }
  if(zero_count > n/2 || any_count + zero_count < n/2) {
    return 0;
  }
  return binomial(any_count, n/2 - zero_count);
}

int main() {

  struct timespec start, end;
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);

  int n;
  scanf("%d", &n);
  int nn = 2 * n;

  int m = 0;
  int m_max = 1024;

  char **masks = malloc(m_max * sizeof(char *));

  while(1) {
    masks[m] = malloc(nn + 1);
    if (scanf("%s", masks[m]) == EOF) {
      break;
    }
    m++;
    if (m == m_max) {
      m_max *= 2;
      masks = realloc(masks, m_max * sizeof(char *));
    }
  }

  int i = 1;
  int i_max = 1024 * 128;

  isct *iscts = malloc(i_max * sizeof(isct));

  iscts[0].mask = malloc(nn);
  iscts[0].p = malloc(m * sizeof(int));

  int j;
  for(j = 0; j < nn; j++) {
    iscts[0].mask[j] = '2';
  }
  for(j = 0; j < m; j++) {
    iscts[0].p[j] = j;
  }
  iscts[0].p_len = m;

  int i_start = 0;
  int i_end = 1;
  int sign = 1;

  long int total = 0;

  int mask_bin_len = 1024 * 1024;
  char* mask_bin = malloc(mask_bin_len);
  int mask_bin_count = 0;

  int p_bin_len = 1024 * 128;
  int* p_bin = malloc(p_bin_len * sizeof(int));
  int p_bin_count = 0;


  while (i_end > i_start) {
    for (j = i_start; j < i_end; j++) {
      if (i + iscts[j].p_len > i_max) {
        i_max *= 2;
        iscts = realloc(iscts, i_max * sizeof(isct));
      }
      isct *isct_orig = iscts + j;
      int x;
      int x_len = 0;
      int i0 = i;
      for (x = 0; x < isct_orig->p_len; x++) {
        if(mask_bin_count + nn > mask_bin_len) {
          mask_bin_len *= 2;
          mask_bin = malloc(mask_bin_len);
          mask_bin_count = 0;
        }
        iscts[i].mask = mask_bin + mask_bin_count;
        mask_bin_count += nn;
        long int count =
            mask_intersect(isct_orig->mask, masks[isct_orig->p[x]], iscts[i].mask, nn);
        if (count > 0) {
          isct_orig->p[x_len] = isct_orig->p[x];
          i++;
          x_len++;
          total += sign * count;
        }
      }
      for (x = 0; x < x_len; x++) {
        int p_len = x_len - x - 1;
        iscts[i0 + x].p_len = p_len;
        if(p_bin_count + p_len > p_bin_len) {
          p_bin_len *= 2;
          p_bin = malloc(p_bin_len * sizeof(int));
          p_bin_count = 0;
        }
        iscts[i0 + x].p = p_bin + p_bin_count;
        p_bin_count += p_len;
        int y;
        for (y = 0; y < p_len; y++) {
          iscts[i0 + x].p[y] = isct_orig->p[x + y + 1];
        }
      }
    }

    sign *= -1;
    i_start = i_end;
    i_end = i;

  }

  printf("%lld\n", total);

  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);

  int seconds = end.tv_sec - start.tv_sec;
  long nanoseconds = end.tv_nsec - start.tv_nsec;
  if(nanoseconds < 0) {
    nanoseconds += 1000000000;
    seconds--;
  }

  printf("%d.%09lds\n", seconds, nanoseconds);
  return 0;
}

উদাহরণস্বরূপ:

robert@unity:~/c/se-mask$ gcc -O3 se-mask.c -lrt -o se-mask
robert@unity:~/c/se-mask$ head testcase-long
30
210211202222222211222112102111220022202222210122222212220210
010222222120210221012002220212102220002222221122222220022212
111022212212022222222220111120022120122121022212211202022010
022121221020201212200211120100202222212222122222102220020212
112200102110212002122122011102201021222222120200211222002220
121102222220221210220212202012110201021201200010222200221002
022220200201222002020110122212211202112011102220212120221111
012220222200211200020022121202212222022012201201210222200212
210211221022122020011220202222010222011101220121102101200122
robert@unity:~/c/se-mask$ ./se-mask < testcase-long
298208861472
0.001615834s
robert@unity:~/c/se-mask$ head testcase-hard
8
0222222222222222
1222222222222222
2022222222222222
2122222222222222
2202222222222222
2212222222222222
2220222222222222
2221222222222222
2222022222222222
robert@unity:~/c/se-mask$ ./se-mask < testcase-hard
12870
3.041261458s
robert@unity:~/c/se-mask$ 

(টাইমস 4.1 গিগাহার্জ একটি i7-4770K CPU- র জন্য আছে।) সাবধান, testcase-hardপ্রায় মেমরি 3-4 গিগাবাইট ব্যবহার।

এটি অন্তর্ভুক্তকরণ-বর্জন পদ্ধতি ব্লুটোরেঞ্জের একটি বাস্তবায়ন এসেছে, তবে এটি কোনও গভীরতার ছেদগুলি পরিচালনা করবে। লিখিত হিসাবে কোডটি মেমরি বরাদ্দকরণে প্রচুর সময় ব্যয় করছে এবং আমি মেমরি পরিচালনার অনুকূলিতকরণের পরে আরও দ্রুততর হয়ে উঠব।

আমি প্রায় 25% চালু করেছিলাম testcase-hard, তবে মূল ( testcase-long) এর পারফরম্যান্সটি অনেকটা অপরিবর্তিত, যেহেতু সেখানে খুব বেশি মেমরি বরাদ্দ চলছে না। আমি এটির কল করার আগে আমি আরও কিছুটা টিউন করতে যাচ্ছি: আমার মনে হয় আমি testcase-longখুব বেশি 25% -50% উন্নতি করতে সক্ষম হব ।

ম্যাথামেটিকাল

একবার আমি লক্ষ্য করলাম এটি একটি # স্যাট সমস্যা হয়ে গেছে, আমি বুঝতে পেরেছি আমি ম্যাথমেটিকার অন্তর্নির্মিতটি ব্যবহার করতে পারি SatisfiabilityCount:

AbsoluteTiming[
 (* download test case *)
 input = Map[FromDigits, 
   Characters[
    Rest[StringSplit[
      Import["http://pastebin.com/raw.php?i=2Dg7gbfV", 
       "Text"]]]], {2}]; n = Length[First[input]];
 (* create boolean function *)
 bool = BooleanCountingFunction[{n/2}, n] @@ Array[x, n] && 
   Or @@ Table[
     And @@ MapIndexed[# == 2 || Xor[# == 1, x[First[#2]]] &, i], {i, 
      input}];
 (* count instances *)
 SatisfiabilityCount[bool, Array[x, n]]
]

আউটপুট:

{1.296944, 298208861472}

এটি পেস্টবিন থেকে পরীক্ষার কেস ডাউনলোড করতে ব্যয় করা সময় সহ 1.3 সেকেন্ডে (i7-3517U @ 1.9 গিগাহার্টজ) 298,208,861,472 মাস্ক


সুতরাং আমি এটি সিটিতে আবার লিখেছি ... দুর্ভাগ্যক্রমে এটির উপরে গ্যাপারফটুলগুলি ব্যবহার করা আমার পক্ষে খুব দ্রুত! আমি আগামীকাল পোস্ট করার আগে আরও কিছু শক্ত পরীক্ষার কেস খুঁজে পাব।
2012campion

testcase-hardআপনার কোডটি যদি সংযুক্ত করা যায় এমন মুখোশগুলির সন্ধান করে তবে খুব দ্রুত সম্পূর্ণ করা যায়। যদি আপনার কোড এটি করে, তবে প্রতিটি অন্যান্য লাইন মুছুন (সুতরাং কেবলমাত্র /^2*02*$/কেসগুলি রয়ে গেছে)। আমি মনে করি না যে মামলাটি অনুকূলিত করা যেতে পারে।
2012campion

4

রুবি, বেশ দ্রুত, তবে এটি ইনপুটটির উপর নির্ভর করে

স্ট্রিং থেকে পূর্ণসংখ্যায় পরিবর্তন করে এখন 2 2 2.5 এর একটি ফ্যাক্টর দ্বারা গতি বাড়ান।

ব্যবহার:

cat <input> | ruby this.script.rb

যেমন।

mad_gaksha@madlab ~/tmp $ ruby c50138.rb < c50138.inp2
number of matches: 298208861472
took 0.05726237 s

একক মাস্কের জন্য মিলগুলির সংখ্যা, যা দ্বিপদী সহগ দ্বারা সহজেই গণনা করা হয়। সুতরাং উদাহরণস্বরূপ 1220203 2টি ভরাট প্রয়োজন, 1 0এবং 2 1। সুতরাং nCr(3,2)=nCr(3,1)=3!/(2!*1!)=3এই মাস্কের সাথে মিলছে বিভিন্ন বাইনারি স্ট্রিং।

N মাস্কস m_1, m_2, ... m_n এর মধ্যে একটি ছেদটি একটি মুখোশ কিউ, যেমন একটি বাইনারি স্ট্রিং এর সাথে Q এর সাথে মেলে তবেই যদি এটি সমস্ত মুখোশ m_i এর সাথে মেলে।

আমরা যদি m_1 এবং m_2 দুটি মুখোশ নিই তবে এর ছেদটি সহজেই গণনা করা যায়। M_1 [i] = m_2 [i] সবেমাত্র m_1 [i] == 2 সেট করুন। 122020এবং এর মধ্যে ছেদটি 111222হল 111020:

122020 (matched by 3 strings, 111000 110010 101010)
111222 (matched by 1 string, 111000)
111020 (matched by 1 string, 111000)

দুটি পৃথক মুখোশ 3 + 1 = 4 স্ট্রিংয়ের সাথে মিলে যায়, ইন্ট্রিেসেকশন মাস্কটি একটি স্ট্রিংয়ের সাথে মিলে যায়, এইভাবে 3 বা 1-1 = 3 টি এক বা উভয় মুখোশের সাথে মিলছে unique

আমি N (m_1, m_2, ...) কে কল করব সমস্ত m_i এর সাথে মিলে থাকা স্ট্রিংয়ের সংখ্যা। উপরের মত একই যুক্তি প্রয়োগ করে আমরা অন্তর্ভুক্তি বাদ দেওয়ার নীতি দ্বারা প্রদত্ত কমপক্ষে একটি মাস্কের সাথে মিলিত অনন্য স্ট্রিংগুলির সংখ্যা গণনা করতে পারি এবং নীচেও এটি দেখতে চাই:

N(m_1) + N(m_2) + ... + N(m_n) - N(m_1,m_2) - ... - N(m_n-1,m_n) + N(m_1,m_2,m_3) + N(m_1,m_2,m_4) + ... N(m_n-2,m_n-1,m_n) - N(m_1,m_2,m_3,m_4) -+ ...

গ্রহণের অনেকগুলি, অনেকগুলি, অনেকগুলি সংমিশ্রণ রয়েছে, বলুন 200 এর মধ্যে 30 টি মাস্ক।

সুতরাং এই সমাধানটি অনুমান করে যে ইনপুট মাস্কগুলির অনেকগুলি উচ্চ-অর্ডার ছেদ নেই, যেমন। বেশিরভাগ এন-টিপলস এন> 2 মাস্কগুলিতে কোনও সাধারণ মিল নেই।

কোডটি এখানে ব্যবহার করুন, আদর্শের কোডটি পুরানো হতে পারে।

আমি একটি ফাংশন যুক্ত করেছি remove_duplicatesযা ইনপুট প্রাক-প্রক্রিয়াজাতকরণ এবং মুখোশগুলি মুছতে ব্যবহার করা যেতে পারে m_iযে এটির সাথে মেলে সমস্ত স্ট্রিং অন্য মুখোশের সাথেও মেলে m_j, সুতরাং, ফাংশনটি এখনও নীচের কোডটিতে ডেটা প্রয়োগ করা হয়নি।

কোড:

# factorial table
FAC = [1]
def gen_fac(n)
  n.times do |i|
    FAC << FAC[i]*(i+1)
  end
end

# generates a mask such that it is matched by each string that matches m and n
def diff_mask(m,n)
  (0..m.size-1).map do |i|
    c1 = m[i]
    c2 = n[i]
    c1^c2==1 ? break : c1&c2
  end
end

# counts the number of possible balanced strings matching the mask
def count_mask(m)
  n = m.size/2
  c0 = n-m.count(0)
  c1 = n-m.count(1)
  if c0<0 || c1<0
    0
  else
    FAC[c0+c1]/(FAC[c0]*FAC[c1])
  end
end

# removes masks contained in another
def remove_duplicates(m)
  m.each do |x|
    s = x.join
    m.delete_if do |y|
      r = /\A#{s.gsub(?3,?.)}\Z/
      (!x.equal?(y) && y =~ r) ? true : false
    end
  end
end

#intersection masks of cn masks from m.size masks
def mask_diff_combinations(m,n=1,s=m.size,diff1=[3]*m[0].size,j=-1,&b)
  (j+1..s-1).each do |i|
    diff2 = diff_mask(diff1,m[i])
    if diff2
      mask_diff_combinations(m,n+1,s,diff2,i,&b) if n<s
      yield diff2,n
    end
  end
end

# counts the number of balanced strings matched by at least one mask
def count_n_masks(m)
  sum = 0
  mask_diff_combinations(m) do |mask,i|
    sum += i%2==1 ? count_mask(mask) : -count_mask(mask)
  end
  sum
end

time = Time.now

# parse input
d = STDIN.each_line.map do |line|
  line.chomp.strip.gsub('2','3')
end
d.delete_if(&:empty?)
d.shift
d.map!{|x|x.chars.map(&:to_i)}

# generate factorial table
gen_fac([d.size,d[0].size].max+1)

# count masks
puts "number of matches: #{count_n_masks(d)}"
puts "took #{Time.now-time} s"

এটিকে অন্তর্ভুক্তি বাদ দেওয়ার নীতি বলা হয়, তবে এর আগে কেউ আমাকে এটি নির্দেশ করার আগে আমার নিজের প্রমাণ ছিল, তাই এখানে চলে যায়। নিজেকে কিছু করা যদিও দুর্দান্ত মনে হয়।

আসুন 2 মাস্কের ক্ষেত্রে বিবেচনা করা যাক, তারপরে প্রথমে কল করুন 0এবং call 1আমরা প্রতিটি সুষম বাইনারি স্ট্রিং নিয়ে থাকি এবং এটি কোন মাস্ক (গুলি) এর সাথে মেলে তার শ্রেণিবদ্ধ করে। c0ঐ যে শুধুমাত্র মেলে মাস্ক সংখ্যা 0, c1ঐ যে শুধুমাত্র মেলে এর nunber 1, c01ঐ যে ম্যাচ মাস্ক 0এবং 1

দিন s0(তারা ওভারল্যাপ পারে) প্রতিটি মাস্ক জন্য ম্যাচ সংখ্যা সংখ্যা সমষ্টি হও। যাক s1মুখোশ প্রতিটি জোড়া (2- সমন্বয়) জন্য ম্যাচ সংখ্যা এর সমষ্টি হও। দিন s_iপ্রতিটি (ঝ + 1) মুখোশ সংযুক্তির জন্য ম্যাচ সংখ্যা এর সমষ্টি হও। এন-মাস্কের মিলগুলির সংখ্যা হ'ল সমস্ত মাস্কের সাথে মেলে বাইনারি স্ট্রিংয়ের সংখ্যা।

যদি এন মাস্ক থাকে তবে কাঙ্ক্ষিত আউটপুট হ'ল সকলের সমষ্টি c, অর্থাৎ। c = c0+...+cn+c01+c02+...+c(n-2)(n-1)+c012+...+c(n-3)(n-2)(n-1)+...+c0123...(n-2)(n-1)। প্রোগ্রামটি কী গণনা করে তা হ'ল সকলের বিকল্প সমষ্টি s, অর্থাত্। s = s_0-s_1+s_2-+...+-s_(n-1)। আমরা তার প্রমাণ করতে চাই s==c

n = 1 সুস্পষ্ট। এন = 2 বিবেচনা করুন। মাস্ক সব ম্যাচ গণনা 0দেয় c0+c01(শুধুমাত্র 0 টি + ঐ ম্যাচিং উভয় মিলে স্ট্রিং সংখ্যা 0এবং 1), সব ম্যাচের বেড়ে চলেছে 1দেয় c1+c02। আমরা নিম্নলিখিত হিসাবে এটি বর্ণনা করতে পারেন:

0: c0 c01
1: c1 c10

সংজ্ঞা দ্বারা s0 = c0 + c1 + c12,। s1হ'ল প্রতিটি 2-সংমিশ্রণের মিলগুলির সংখ্যার [0,1]অর্থাত্‍। সমস্ত ইউনিট c_ijs। মনে রাখবেন c01=c10

s0 = c0 + c1 + 2 c01
s1 = c01
s = s0 - s1 = c0 + c1 + c01 = c

এভাবে s=cএন = 2 এর জন্য।

এখন এন = 3 বিবেচনা করুন।

0  : c0 + c01 + c02 + c012
1  : c1 + c01 + c12 + c012
2  : c2 + c12 + c02 + c012
01 : c01 + c012
02 : c02 + c012
12 : c12 + c012
012: c012

s0 = c0 + c1 + c2 + 2 (c01+c02+c03) + 3 c012
s1 = c01 + c02 + c12 + 3 c012
s2 = c012

s0 = c__0 + 2 c__1 + 3 c__2
s1 =          c__1 + 3 c__2
s2 =                   c__2

s = s0 - s1 + s2 = ... = c0 + c1 + c2 + c01 + c02 + c03 + c012 = c__0 + c__1 + c__2 = c

এইভাবে s=cএন = 3 এর জন্য। c__iসব প্রতিনিধিত্ব করে c(আমি + 1) সূচকের যেমন সঙ্গে গুলি c__1 = c01এন = 2 এবং c__1 = c01 + c02 + c12ঢ == 3 জন্য।

N = 4 এর জন্য, একটি প্যাটার্ন উত্থিত হতে শুরু করে:

0:   c0 + c01 + c02 + c03 + c012 + c013 + c023 + c0123
1:   c1 + c01 + c12 + c13 + c102 + c103 + c123 + c0123
2:   c2 + c02 + c12 + c23 + c201 + c203 + c213 + c0123
3:   c3 + c03 + c13 + c23 + c301 + c302 + c312 + c0123

01:  c01 + c012 + c013 + c0123
02:  c02 + c012 + c023 + c0123
03:  c03 + c013 + c023 + c0123
12:  c11 + c012 + c123 + c0123
13:  c13 + c013 + c123 + c0123
23:  c23 + c023 + c123 + c0123

012:  c012 + c0123
013:  c013 + c0123
023:  c023 + c0123
123:  c123 + c0123

0123: c0123

s0 = c__0 + 2 c__1 + 3 c__2 + 4 c__3
s1 =          c__1 + 3 c__2 + 6 c__3
s2 =                   c__2 + 4 c__3
s3 =                            c__3

s = s0 - s1 + s2 - s3 = c__0 + c__1 + c__2 + c__3 = c

এইভাবে s==cএন = 4 এর জন্য।

সাধারণভাবে, আমরা এর মতো দ্বিপদী সহগগুলি পাই (get আমি,, হ'ল জে):

   0  1  2  3  4  5  6  .  .  .

0  1  2  3  4  5  6  7  .  .  .
1     1  3  6  10 15 21 .  .  .
2        1  4  10 20 35 .  .  .
3           1  5  15 35 .  .  .
4              1  6  21 .  .  .
5                 1  7  .  .  .
6                    1  .  .  . 
.                       .
.                          .
.                             .

এটি দেখতে, কিছু iএবং এটির জন্য বিবেচনা করুন j:

  • x = এনসিআর (এন, আই + 1): সংযোগ সি সি থেকে (i + 1) মুখোশের ছেদ জন্য
  • y = এনসিআর (এনআই -১, জি): উপরের প্রতিটি সংমিশ্রণের জন্য, সি রয়েছে এমনগুলির মধ্যে (জে + ২) মুখোশের ছেদ করার জন্য y বিভিন্ন সংমিশ্রণ রয়েছে
  • z = এনসিআর (এন, জে + 1): এন এর বাইরে (জে + 1) মুখোশের ছেদ করার জন্য বিভিন্ন সংমিশ্রণ

যেহেতু বিভ্রান্তিমূলক মনে হতে পারে, এখানে একটি উদাহরণের সাথে সংজ্ঞাটি প্রয়োগ করা হয়েছে। I = 1, j = 2, n = 4 এর জন্য দেখতে এটি দেখতে (সিএফ। উপরে):

01:  c01 + c012 + c013 + c0123
02:  c02 + c012 + c023 + c0123
03:  c03 + c013 + c023 + c0123
12:  c11 + c012 + c123 + c0123
13:  c13 + c013 + c123 + c0123
23:  c23 + c023 + c123 + c0123

সুতরাং এখানে x = 6 (01, 02, 03, 12, 13, 23), y = 2 (প্রতিটি সংমিশ্রনের জন্য তিনটি সূচক সহ দুটি সি), z = 4 (c012, c013, c023, c123)।

মোট, (জে + 1) সূচক সহ x*yসহগ আছে c, এবং zবিভিন্ন আছে , তাই প্রতিটি সময় ঘটে x*y/z, যা আমরা সহগ বলি k_ij। সহজ বীজগণিত দ্বারা, আমরা পেতে k_ij = ncr(n,i+1) ncr(n-i-1,j-i) / ncr(n,j+1) = ncr(j+1,i+1)

সুতরাং সূচকটি দেওয়া হয় k_ij = nCr(j+1,i+1)যদি আপনি সমস্ত সংজ্ঞাগুলি স্মরণ করেন তবে আমাদের কেবলমাত্র দেখাতে হবে যে প্রতিটি কলামের বিকল্প যোগফল 1 দেয়।

বিকল্প যোগফলটি s0 - s1 + s2 - s3 +- ... +- s(n-1)এভাবে প্রকাশ করা যেতে পারে:

s_j = c__j * ∑[(-1)^(i+j) k_ij] for i=0..n-1
     = c__j * ∑[(-1)^(i+j) nCr(j+1,i+1)] for i=0..n-1
     = c__j * ∑[(-1)^(i+j) nCr(j+1,i)]{i=0..n} - (-1)^0 nCr(j+1,0)
     = (-1)^j c__j

s   = ∑[(-1)^j  s_j] for j = 0..n-1
    = ∑[(-1)^j (-1)^j c__j)] for j=0..n-1
    = ∑[c__j] for j=0..n-1
    = c

এভাবে s=cসমস্ত এন = 1,2,3, ...


1
আপনি সচেতন কিনা তা সম্পর্কে আমি নিশ্চিত নই, তবে আপনি যে পদ্ধতিটি প্রয়োগ করছেন তা হ'ল এন.ইউইকিপিডিয়া.আর / উইকি / ইনক্লুশন ৯০২৯০.০৯৯৯ এক্সক্লুসিশন_প্রিন্সিপাল , তাই আপনি এটি প্রমাণ করতে হবে না, যদি আপনি যা চেষ্টা করে যাচ্ছেন না। এছাড়াও পরীক্ষার ক্ষেত্রে প্রয়োজন না থাকায় আপনি গ্রুপের মুখোশগুলি পুরোপুরি গোষ্ঠীর অন্য একটি মুখোশের অন্তর্ভুক্ত থেকে সরিয়ে নিতে পারেন। TC5 মধ্যে উদাহরণস্বরূপ: 0011 < 2211, 0022 < 0222। আমি মনে করি যে এটি গ্রুপগুলি এর চেয়ে বড় কিছু করে না 2*n, যদিও এটি এখনও সবচেয়ে খারাপ ক্ষেত্রে।
নটকি

@ নটকি আমি এ সম্পর্কে অবগত ছিলাম না, তাই লিঙ্কটির জন্য ধন্যবাদ। মাঝে মাঝে, নিজের জন্য কিছু প্রমাণ করা এবং চিন্তা করা এখনও একটি দুর্দান্ত অনুশীলন, যদিও :)। আপনার পরামর্শ হিসাবে, হ্যাঁ, এটি আমার কাছে ঘটেছিল, তবে আমি মনে করি না যে আমি কোনও পরীক্ষার কেস যুক্ত না করা হলে এটি যুক্তিযুক্ত সময় হিসাবে ফলাফল পাওয়ার প্রয়োজন হয় না আমি এটি প্রয়োগ করব to
ব্লুঞ্জরাইজ

@ ব্লুটোরেঞ্জ আপনি কি সিদ্ধান্ত গাছ ব্যবহার করার কথা ভাবেন?
Abr001am

আমার মনে হয় আপনি ছেদটি বোঝাচ্ছেন (উভয় মুখোশের সাথে মেলে), ইউনিয়ন নয় (এক বা অন্য মুখোশের সাথে মেলে)।
2012campion

@ ২০১২ সিআরপিওন unifying two masksশব্দটি যেমন unionআমার কাছে বোধগম্য হয়েছে এবং আমি সেভাবে সংজ্ঞা দিচ্ছি তবে আপনি ঠিক বলেছেন, পারস্পরিক বোঝাপড়ার আগ্রহেই আমি জড়িয়ে পড়েছি। @ আগওয়া 1001 আপনি কি আরও নির্দিষ্ট হতে পারেন? এছাড়াও, যদি আপনি এটিকে দ্রুত করার জন্য কিছু ভাল ধারণা পেয়ে থাকেন তবে আপনার প্রোগ্রাম / উত্তরের জন্য এই উত্তর থেকে কোনও ধারণা ব্যবহার করতে নির্দ্বিধায় হন। আপাতত, এটি বড় পরীক্ষার ক্ষেত্রে যথেষ্ট দ্রুত, এবং যদি বহু-থ্রেডযুক্ত করা হয় তবে এটি <0.1s গ্রহণ করা উচিত, যা কোনও অর্থবোধক পরিমাপ / তুলনার চেয়ে নীচে, সুতরাং কঠোর পরীক্ষার ক্ষেত্রে প্রয়োজন are
ব্লুটোরেঞ্জ

1

সি

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gsl/gsl_combination.h>

int main (int argc, char *argv[]) {

    printf ("reading\n");
    char buffer[100];
    gets(buffer);
    char n = atoi(buffer);

    char *masks[1000];
    masks[0] = malloc(2 * n * sizeof(char));
    char c,nrows,j,biggestzerorun,biggestonerun,currentzerorun,currentonerun = 0;

    while ((c = getchar()) && c != EOF) {
        if (c == '\n') {
            nrows++;
            if (currentonerun > biggestonerun) {
                biggestonerun = currentonerun;
            }
            if (currentzerorun > biggestzerorun) {
                biggestzerorun = currentzerorun;
            }
            j=currentonerun=currentzerorun=0;
            masks[nrows] = malloc(2 * n * sizeof(char));
        } else if (c == '0') {
            masks[nrows][j++] = 1;
            currentzerorun++;
            if (currentonerun > biggestonerun) {
                biggestonerun = currentonerun;
            }
            currentonerun=0;
        } else if (c == '1') {
            masks[nrows][j++] = 2;
            currentonerun++;
            if (currentzerorun > biggestzerorun) {
                biggestzerorun = currentzerorun;
            }
            currentonerun=0;
        } else if (c == '2') {
            masks[nrows][j++] = 3;
            currentonerun++;
            currentzerorun++;
        }
    }
    if (currentonerun > biggestonerun) {
        biggestonerun = currentonerun;
    }
    if (currentzerorun > biggestzerorun) {
        biggestzerorun = currentzerorun;
    }

    printf("preparing combinations\n");

    int nmatches=0;

    gsl_combination *combination = gsl_combination_calloc(2*n, n);

    printf("entering loop:\n");

    do {
        char vector[2*n];
        char currentindex, previousindex;
        currentonerun = 0;
        memset(vector, 1, 2*n);


        // gsl_combination_fprintf (stdout, combination, "%u ");
        // printf(": ");

        for (char k=0; k<n; k++) {
            previousindex = currentindex;
            currentindex = gsl_combination_get(combination, k);
            if (k>0) {
                if (currentindex - previousindex == 1) {
                    currentonerun++;
                    if (currentonerun > biggestonerun) {
                        goto NEXT;
                    }
                } else {
                    currentonerun=0;
                    if (currentindex - previousindex > biggestzerorun) {
                        goto NEXT;
                    }
                }
            }
            vector[currentindex] = 2;
        }

        for (char k=0; k<=nrows; k++) {
            char ismatch = 1;
            for (char l=0; l<2*n; l++) {
                if (!(vector[l] & masks[k][l])) {
                    ismatch = 0;
                    break;
                }
            }
            if (ismatch) {
                nmatches++;
                break;
            }
        }

        NEXT: 1;

    } while (
        gsl_combination_next(combination) == GSL_SUCCESS
    );

    printf ("RESULT: %i\n", nmatches);

    gsl_combination_free(combination);
    for (; nrows>=0; nrows--) {
        free(masks[nrows]);
    }
}

শুভকামনা এটিকে চালানোর জন্য বড় ইনপুট পাচ্ছে - প্রায় সম্ভবত পুরো রাতটি লাগবে। 60 ^ 30 অনুমতি! হতে পারে একটি মধ্যবর্তী আকারের ডেটাসেটটি ভাল ধারণা হতে পারে?

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.