বৈদ্যুতিক গ্রিড তৈরি করুন


22

চ্যালেঞ্জ

একটি সরল লাইনে সারিবদ্ধভাবে এন সিটি রয়েছে। আই-থ্রি শহরটি A[i]উত্সের ডানদিকে কিলোমিটারে অবস্থিত । কোনও দুটি শহর একই জায়গায় থাকবে না।

আপনি কিছু বিদ্যুৎকেন্দ্র সহ একটি বৈদ্যুতিক গ্রিড তৈরি করতে যাচ্ছেন। একটি বিদ্যুত কেন্দ্র স্থাপন করতে হবে। তবে, আপনাকে কেবল K(<এন) বিদ্যুৎ কেন্দ্র নির্মাণের অনুমতি দেওয়া হয়েছে , সুতরাং কিছু শহর থাকবে যার মধ্যে বিদ্যুৎকেন্দ্র নেই। বিদ্যুৎ কেন্দ্রবিহীন প্রতিটি শহরের জন্য আপনাকে অবশ্যই এটির এবং এর মধ্যে একটি তারের তৈরি করতে হবে নিকটতম শহরের যেটির একটি বিদ্যুৎকেন্দ্র রয়েছে

উদাহরণস্বরূপ, যদি তিনটি অবস্থিত শহর 0, 1, 2, এবং শুধুমাত্র শহর এ 0বিদ্যুৎ কেন্দ্র আছে, আপনি দুই তারের, থেকে এক নির্মাণ করা প্রয়োজন 2থেকে 0(2km) এবং থেকে অন্য 1থেকে0 (1 কিমির), যা 3Km মোট দৈর্ঘ্য আছে ।

দেওয়া Kএবং শহরগুলির অবস্থান (A ), আপনি তারের ন্যূনতম কিলোমিটার আপনি গ্রিড নির্মাণ করা প্রয়োজন গনা করা উচিত নয়।

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

K = 1, A = [0, 2, 4, 6, 8] : 12 
# build power plant in the city at position 4, total length = 4 + 2 + 0 + 2 + 4 = 12

K = 3, A = [0, 1, 10, 11, 20, 21, 22, 30, 32] : 23
# build power plants in cities at positions 0, 10 and 22

K = 5, A = [0, 1, 3, 6, 8, 11, 14] : 3
# build power plants in all cities except those at positions 0, 3

K = 6, A = [0, 1, 3, 6, 8, 14, 15, 18, 29, 30, 38, 41, 45, 46, 49, 58, 66, 72, 83, 84] : 49

বিশেষ উল্লেখ

  • আপনার কোনও ক্রিয়াকলাপ বা একটি প্রোগ্রাম বাস্তবায়ন করা উচিত, এটি ইতিবাচক পূর্ণসংখ্যার Kএবং পূর্ণসংখ্যার একটি তালিকা গ্রহণ করেA কোনও রূপের এবং উত্তরটি উপস্থাপন করে কোনও পূর্ণসংখ্যার আউটপুট / ফিরিয়ে দেয়।

  • A আরোহী ক্রম অনুসারে বাছাই করা হয় এবং সমস্ত উপাদান অ-নেতিবাচক পূর্ণসংখ্যার হয়।

  • A[0] = 0, এবং A[N-1]1000N এর বেশি হবে না।

  • নোট করুন যে আউটপুটটি 1000N 2 এর আকারের হবে , সুতরাং বড় ক্ষেত্রে, আপনার কয়েকটি ভাষায় 64৪-বিট পূর্ণসংখ্যার প্রয়োজন হতে পারে।

  • Multithreading হয় না দেয়া (যখন বিচার আমি শুধুমাত্র 1 কোটি আপনার প্রোগ্রামের সম্বন্ধ সেট করবে)। সংকলক অপ্টিমাইজেশান (যেমন -O2সি হিসাবে ) অনুমোদিত।

স্কোরিং

  • আমি আমার কম্পিউটারে আপনার কোডটি (ইনটেল আই 7-3770S প্রসেসরের সাথে উবুন্টু 16.04) টাইমকেসগুলির বিভিন্ন আকারের সাথে সময় করব। বিশেষত, আমি এন = ফ্লোর (2 এক্স / 5 ) দিয়ে কিছু টেস্টকেস তৈরি করব যেখানে এক্সটি ধনাত্মক পূর্ণসংখ্যা।
    আপনার স্কোরটি সবচেয়ে ছোট টেস্টকেসের x মান হবে যা আপনার প্রোগ্রাম 10 সেকেন্ডের বেশি বা 1 জিআইবি মেমরি ব্যবহার করে বা সঠিক উত্তর দেয় না।

    • উত্তর সর্বোচ্চ স্কোর জিতেছে। যদি দুটি উত্তর একই স্কোর পায় তবে আগের উত্তরটি জিতবে।
  • সমস্ত প্রোগ্রামের টেস্টকেসের একই সেট দ্বারা বিচার করা হবে।

  • আপনার নিজের স্কোরিং পোস্ট করতে নির্দ্বিধায়। আপনার অ্যালগরিদমের ব্যাখ্যা উত্সাহিত করা হয়।

বোনাস

এটি আমার সি ++ প্রোগ্রাম, এটির স্কোর 108 । আপনি SHA-256 ডাইজেস্ট যাচাই করতে পারেন9a87fa183bad1e3a83d2df326682598796a216b3a4262c32f71dfb06df12935d লিঙ্কের পুরো কোড বিভাগ (পাদলেখ ছাড়াই) দ্বারা ।

অ্যালগরিদম বাইনারি অনুসন্ধান এবং নুথের অপ্টিমাইজেশানের সাথে একত্রে পছন্দসই নম্বর পেতে প্রতিটি গাছের সঠিক জরিমানা খুঁজে বের করে। জটিলতা হ'ল হে (এন লগ এন লগ এ [এন -1])। আমি আশ্চর্য হয়ে গেলাম যে প্রোগ্রামটি অ্যান্ডারস কাসেরগের ও (এন লগ এ [এন − 1]) সমাধানের চেয়ে উচ্চতর স্কোর পেয়েছে । এটি সম্ভবত নূটের অপ্টিমাইজেশনে লগ কেসটি ঘটবে না এর কারণেই।

নোট করুন যে এই চ্যালেঞ্জটি আইওআই 2000 পোস্ট অফিসের মতো । মূল সীমাবদ্ধতাগুলি হ'ল এন <= 300 এবং কে <= 30, যদিও।


2^^(x/5): অর্থ কি ? আপনি কি কেবল এন এর জন্য একটি উপরের বাউন্ড সরবরাহ করতে পারেন?
13

1
@ সেটপ উদাহরণস্বরূপ, যদি আপনার প্রোগ্রামটি N=21( = floor(2^(22/5)) )10 সেকেন্ডের মধ্যে ডিল করতে পারে তবে তা মোকাবেলা করতে না N=24( = floor(2^(23/5)) )পারে তবে ২৩ নম্বর হবে। আমি একটি উচ্চতর গণ্ডি ব্যবহার করিনি, যেহেতু বিভিন্ন অ্যালগরিদমের মধ্যে পার্থক্য খুব দুর্দান্ত। উদাহরণস্বরূপ, যদি আমি এন <= 40 সেট করি তবে এর মধ্যে সামান্য পার্থক্য হবে O(KN^2)এবং O(KN^3)তবে O(2^N)অনুরণনযোগ্য সময়ে এটি শেষও হবে না।
কলেরা সু

5
এটি জীবিতের জন্য আমি যা করি তা হ'ল এবং আমি আপনাকে এটি অনেক কিছু বলতে পারি: আমরা বৈদ্যুতিক গ্রিডটি ডিজাইন করার উপায় এটি নয়!
স্টিভি গ্রিফিন


3
দুর্দান্ত চ্যালেঞ্জ, দুর্দান্ত স্কোরিং সিস্টেম। সাবাশ!
isaacg

উত্তর:


9

মরিচা , স্কোর = 104

এটি গ্রানলন্ড এট আল দ্বারা চিহ্নিত অ্যালগরিদমের একটি বাস্তবায়ন (2017) §3.3.1 এর শেষে, যদিও আমাকে একটি দীর্ঘ উদ্ধৃতি শৃঙ্খলা অনুসরণ করতে হয়েছিল এবং কিছু অনুপস্থিত বিশদটি পূরণ করতে হয়েছিল। এটি ( এন লগ [ এন) এ চলে - 1]) সময়ে চলে।

সঙ্গে সংকলন rustc -O। ইনপুট ফর্ম্যাটটি Kপ্রথম লাইনে রয়েছে, তারপরে Aলাইন প্রতি একটি প্রবেশিকা, সমস্ত স্টিডিনে।

(দ্রষ্টব্য: আমি এই উদ্বোধনের সময়সীমার এক ঘন্টা পরে জমা দিচ্ছি, তবে আমি উদ্বোধনের সময়সীমার আগে জমা দেওয়া শেষ সংস্করণটি আশা করব যা হে ( এন লগ এন লগ [ এন - 1]) সময় , প্রায় 94 স্কোর করার জন্য ।)

use std::cmp::min;
use std::io::{self, BufRead};
use std::iter::{once, Cloned};
use std::num::Wrapping;
use std::ops::Range;
use std::slice;
use std::time::Instant;
use std::u64;

type Cost = u64;
const INF: Cost = u64::MAX;

trait ColsTrait<Col>: Clone {
    type Iter: Iterator<Item = Col>;
    fn len(&self) -> usize;
    fn iter(&self) -> Self::Iter;
    fn slice(&self, range: Range<usize>) -> Self;
}

impl<'a, Col: Clone> ColsTrait<Col> for &'a [Col] {
    type Iter = Cloned<slice::Iter<'a, Col>>;
    fn len(&self) -> usize {
        (*self).len()
    }
    fn iter(&self) -> Self::Iter {
        (*self).iter().cloned()
    }
    fn slice(&self, range: Range<usize>) -> Self {
        unsafe { self.get_unchecked(range) }
    }
}

impl ColsTrait<usize> for Range<usize> {
    type Iter = Range<usize>;
    fn len(&self) -> usize {
        self.end - self.start
    }
    fn iter(&self) -> Range<usize> {
        self.clone()
    }
    fn slice(&self, range: Range<usize>) -> Self {
        Range {
            start: self.start + range.start,
            end: self.start + range.end,
        }
    }
}

fn smawk<Col: Copy, Cols: ColsTrait<Col>, Key: Ord, F: Copy + Fn(usize, Col) -> Key>(
    n: usize,
    shift: u32,
    cols: Cols,
    f: F,
) -> Vec<usize> {
    if n == 0 {
        Vec::new()
    } else if cols.len() > n {
        let mut s = Vec::with_capacity(n);
        let mut sk = Vec::with_capacity(n);
        for (jk, j) in cols.iter().enumerate() {
            while match s.last() {
                Some(&l) => f(!(!(s.len() - 1) << shift), j) <= f(!(!(s.len() - 1) << shift), l),
                None => false,
            } {
                s.pop();
                sk.pop();
            }
            if s.len() < n {
                s.push(j);
                sk.push(jk);
            }
        }
        smawk1(
            n,
            shift,
            cols,
            f,
            smawk(n / 2, shift + 1, &s[..], f)
                .into_iter()
                .map(|h| unsafe { *sk.get_unchecked(h) }),
        )
    } else {
        smawk1(
            n,
            shift,
            cols.clone(),
            f,
            smawk(n / 2, shift + 1, cols, f).into_iter(),
        )
    }
}

fn smawk1<
    Col: Copy,
    Cols: ColsTrait<Col>,
    Key: Ord,
    F: Fn(usize, Col) -> Key,
    Iter: Iterator<Item = usize>,
>(
    n: usize,
    shift: u32,
    cols: Cols,
    f: F,
    iter: Iter,
) -> Vec<usize> {
    let mut out = Vec::with_capacity(n);
    let mut range = 0..0;
    for (i, k) in iter.enumerate() {
        range.end = k + 1;
        out.push(
            range
                .clone()
                .zip(cols.slice(range.clone()).iter())
                .min_by_key(|&(_, col)| f(!(!(2 * i) << shift), col))
                .unwrap()
                .0,
        );
        out.push(k);
        range.start = k;
    }
    if n % 2 == 1 {
        range.end = cols.len();
        out.push(
            range
                .clone()
                .zip(cols.slice(range.clone()).iter())
                .min_by_key(|&(_, col)| f(!(!(n - 1) << shift), col))
                .unwrap()
                .0,
        );
    }
    out
}

fn solve(k: usize, a: &[Cost]) -> Cost {
    if k >= a.len() {
        return 0;
    }
    let sa = once(Wrapping(0))
        .chain(a.iter().scan(Wrapping(0), |s, &x| {
            *s += Wrapping(x);
            Some(*s)
        }))
        .collect::<Vec<_>>();
    let c = |i: usize, j: usize| {
        let h = (i - j) / 2;
        unsafe {
            (sa.get_unchecked(i) - sa.get_unchecked(i - h) - sa.get_unchecked(j + h)
                + sa.get_unchecked(j))
                .0
        }
    };
    let cost1 = c(a.len(), 0);
    if k == 1 {
        return cost1;
    }
    let cost2 = (1..a.len()).map(|j| c(j, 0) + c(a.len(), j)).min().unwrap();
    let mut low = 0;
    let mut high = cost1 - cost2;
    let mut ret = INF;
    while low <= high {
        let penalty = low + (high - low) / 2;
        let mut out = vec![(INF, 0); a.len() + 1];
        out[0] = (0, 0);
        let mut begin = 0;
        let mut chunk = 1;
        loop {
            let r = min(a.len() + 1 - begin, 2 * chunk);
            let edge = begin + chunk;
            let (out0, out1) = out.split_at_mut(edge);
            let f = |i: usize, j: usize| {
                let h = (edge + i - j) / 2;
                let &(cost, count) = unsafe { out0.get_unchecked(j) };
                (
                    cost.saturating_add(
                        unsafe {
                            sa.get_unchecked(edge + i) - sa.get_unchecked(edge + i - h)
                                - sa.get_unchecked(j + h)
                                + sa.get_unchecked(j)
                        }.0 + penalty,
                    ),
                    count + 1,
                )
            };
            for ((i, j), o) in smawk(r - chunk, 0, begin..edge, &f)
                .into_iter()
                .enumerate()
                .zip(out1.iter_mut())
            {
                *o = min(f(i, begin + j), *o);
            }
            let x = unsafe { out1.get_unchecked(r - 1 - chunk) };
            if let Some(j) = (edge..begin + r - 1).find(|&j| &f(r - 1 - chunk, j) <= x) {
                begin = j;
                chunk = 1;
            } else if r == a.len() + 1 - begin {
                break;
            } else {
                chunk *= 2;
            }
        }
        let &(cost, count) = unsafe { out.get_unchecked(a.len()) };
        if count > k {
            low = penalty + 1;
        } else {
            ret = cost.wrapping_sub(k as Cost * penalty);
            if count == k {
                return ret;
            }
            high = penalty - 1;
        }
    }
    ret
}

fn main() {
    let stdin = io::stdin();
    let mut lines = stdin.lock().lines();
    let k = lines.next().unwrap().unwrap().parse().unwrap();
    let a = lines
        .map(|s| s.unwrap().parse().unwrap())
        .collect::<Vec<_>>();
    let start = Instant::now();
    let cost = solve(k, &a);
    let time = start.elapsed();
    println!(
        "cost: {}\ntime: {}.{:09} sec",
        cost,
        time.as_secs(),
        time.subsec_nanos()
    );
}

এটি অনলাইন চেষ্টা করুন!

মরিচা , প্রিস্টেস্ট স্কোর = 73

সঙ্গে সংকলন rustc -O। ইনপুট ফর্ম্যাটটি Kপ্রথম লাইনে রয়েছে, তারপরে Aলাইন প্রতি একটি প্রবেশিকা, সমস্ত স্টিডিনে।

use std::io::{self, BufRead};
use std::iter::once;
use std::num::Wrapping;
use std::time::Instant;
use std::u64;

type Cost = u64;
const INF: Cost = u64::MAX;

fn smawk<Col: Clone, Key: Ord, F: Clone + Fn(usize, &Col) -> Key>(
    n: usize,
    shift: u32,
    cols: &[Col],
    f: F,
) -> Vec<usize> {
    if n == 0 {
        Vec::new()
    } else if cols.len() > n {
        let mut s = Vec::with_capacity(n);
        let mut sk = Vec::with_capacity(n);
        for (jk, j) in cols.iter().enumerate() {
            while match s.last() {
                Some(l) => f(!(!(s.len() - 1) << shift), j) <= f(!(!(s.len() - 1) << shift), l),
                None => false,
            } {
                s.pop();
                sk.pop();
            }
            if s.len() < n {
                s.push(j.clone());
                sk.push(jk);
            }
        }
        smawk1(
            n,
            shift,
            cols,
            f.clone(),
            smawk(n / 2, shift + 1, &s, f)
                .into_iter()
                .map(|h| unsafe { *sk.get_unchecked(h) }),
        )
    } else {
        smawk1(
            n,
            shift,
            cols,
            f.clone(),
            smawk(n / 2, shift + 1, &cols, f).into_iter(),
        )
    }
}

fn smawk1<Col: Clone, Key: Ord, F: Clone + Fn(usize, &Col) -> Key, Iter: Iterator<Item = usize>>(
    n: usize,
    shift: u32,
    cols: &[Col],
    f: F,
    iter: Iter,
) -> Vec<usize> {
    let mut out = Vec::with_capacity(n);
    let mut range = 0..0;
    for (i, k) in iter.enumerate() {
        range.end = k + 1;
        out.push(
            range
                .clone()
                .zip(unsafe { cols.get_unchecked(range.clone()) })
                .min_by_key(|&(_, col)| f(!(!(2 * i) << shift), col))
                .unwrap()
                .0,
        );
        out.push(k);
        range.start = k;
    }
    if n % 2 == 1 {
        range.end = cols.len();
        out.push(
            range
                .clone()
                .zip(unsafe { cols.get_unchecked(range.clone()) })
                .min_by_key(|&(_, col)| f(!(!(n - 1) << shift), col))
                .unwrap()
                .0,
        );
    }
    out
}

fn solve(k: usize, a: &[Cost]) -> Cost {
    let mut cost = vec![INF; a.len() + 1 - k];
    let sa = once(Wrapping(0))
        .chain(a.iter().scan(Wrapping(0), |s, &x| {
            *s += Wrapping(x);
            Some(*s)
        }))
        .collect::<Vec<_>>();
    cost[0] = 0;
    let cols = (0..a.len() + 1 - k).collect::<Vec<_>>();
    for m in 0..k {
        cost = {
            let f = |i: usize, &j: &usize| {
                if i + 1 >= j {
                    let h = (i + 1 - j) / 2;
                    unsafe {
                        cost.get_unchecked(j).saturating_add(
                            (sa.get_unchecked(i + m + 1) - sa.get_unchecked(i + m + 1 - h)
                                - sa.get_unchecked(j + m + h)
                                + sa.get_unchecked(j + m))
                                .0,
                        )
                    }
                } else {
                    INF
                }
            };
            smawk(a.len() + 1 - k, 0, &cols, &f)
                .into_iter()
                .enumerate()
                .map(|(i, j)| f(i, &j))
                .collect()
        };
    }
    cost[a.len() - k]
}

fn main() {
    let stdin = io::stdin();
    let mut lines = stdin.lock().lines();
    let k = lines.next().unwrap().unwrap().parse().unwrap();
    let a = lines
        .map(|s| s.unwrap().parse().unwrap())
        .collect::<Vec<_>>();
    let start = Instant::now();
    let cost = solve(k, &a);
    let time = start.elapsed();
    println!(
        "cost: {}\ntime: {}.{:09} sec",
        cost,
        time.as_secs(),
        time.subsec_nanos()
    );
}

এটি অনলাইন চেষ্টা করুন!


আপনি একটি সেরা স্কোর পেয়েছেন 61, কিন্তু এটি কারণ ওভারফ্লো u32। হতে পারে আপনি 64-বিট পূর্ণসংখ্যার ধরণে পরিবর্তন করতে পারেন?
কোলেরা সু

@ কোলেরাসু যদি আমি স্রেফ পরিবর্তিত হই তবে কি এটি আরও ভাল type Cost = u32হয় type Cost = u64?
অ্যান্ডারস কাসরগ

1
বাহ, আমি কখনও এসএমএডাব্লুকে আলগোরিদিম সম্পর্কে ভাবি নি। ভাল কাজ, আপনি পেয়েছেন 73
কলেরা সু

2
@ngn জং এর বিরুদ্ধে আপনার কী আছে? :-(
অ্যান্ডার্স কাসরগ

1
প্রথম অনুগ্রহ জিতে অভিনন্দন!
ousurous

5

সি, স্কোর = 56

এর বিষয়বস্তু a.c:

typedef void V;typedef char C;typedef long L;typedef unsigned long U;
#define R return
#define W while
#define S static
#include<sys/syscall.h>
#define h1(f,x    )({L r;asm volatile("syscall":"=a"(r):"0"(SYS_##f),"D"(x)              :"cc","rcx","r11","memory");r;})
#define h3(f,x,y,z)({L r;asm volatile("syscall":"=a"(r):"0"(SYS_##f),"D"(x),"S"(y),"d"(z):"cc","rcx","r11","memory");r;})
#define read(a...) h3(read ,a)
#define write(a...)h3(write,a)
#define exit(a...) h1(exit ,a)
S V P(U x){C s[32],*p=s+32;*--p='\n';do{*--p='0'+x%10;x/=10;}W(x);write(1,p,s+32-p);}
S V mc(V*x,V*y,L n){C*p=x,*q=y;for(L i=0;i<n;i++)p[i]=q[i];}
#define min(x,y)({typeof(x)_x=(x),_y=(y);_x+(_y-_x)*(_y<_x);})
#define t(x,i,j)x[(i)*(n+n-(i)+1)/2+(j)] //triangle indexing
#define x(i,j)t(x,i,j)
#define y(i,j)t(y,i,j)
#define z(i,j)t(z,i,j)
#define N 4096 //max
L n;U ka[N+1],c[N],x[N*(N+1)/2],y[N*(N+1)/2],z[N*(N+1)/2];
V _start(){
 C s[1<<20];L r=0;U v=0;
 W(0<(r=read(0,s,sizeof(s))))for(L i=0;i<r;i++)if('0'<=s[i]&&s[i]<='9'){v=s[i]-'0'+10*v;}else{ka[n++]=v;v=0;}
 n--;U k=*ka,*a=ka+1;
 for(L i=n-1;i>=0;i--)for(L j=i-1;j>=0;j--)x(j,i)=x(j+1,i)-a[j]+a[i];
 for(L i=0;i<n;i++)for(L j=i+1;j<n;j++)y(i,j)=y(i,j-1)+a[j]-a[i];
 for(L i=n-1;i>=0;i--)for(L j=i+1;j<n;j++){
  U v=~0ul,*p=&x(i,i),*q=&y(i,j);for(L l=i;l<j;l++){v=min(v,*p+++*q);q+=n-l;} //min(v,x(i,l)+y(l,j));
  z(i,j)=v;}
 mc(c,z,8*n);
 for(L m=1;m<k;m++)for(L j=n-1;j>=m;j--){
  U v=~0ul,*p=&z(j,j);for(L i=j-1;i>=m-1;i--){v=min(v,c[i]+*p);p-=n-i;} //min(v,c[i]+z(i+1,j))
  c[j]=v;}
 P(c[n-1]);exit(0);}

উপরোক্ত সংকলন এবং পরীক্ষা করতে শেল স্ক্রিপ্ট:

#!/bin/bash -e
clang -O3 -nostdlib -ffreestanding -fno-unwind-tables -fno-unroll-loops -fomit-frame-pointer -oa a.c
strip -R.comment -R'.note*' a;stat -c'size:%s' a
t(){ r="$(echo "$1"|./a)";if [ "$r" != "$2" ];then echo "in:$1, expected:$2, actual:$r";fi;} #func tests
t '1 0 2 4 6 8' 12
t '3 0 1 10 11 20 21 22 30 32' 23
t '5 0 1 3 6 8 11 14' 3
t '6 0 1 3 6 8 14 15 18 29 30 38 41 45 46 49 58 66 72 83 84' 49
t '2 0 7 9' 2
for n in 1176 1351 1552 1782 2048;do #perf test
 echo "n:$n";a=0 inp="$((2*n/3))" RANDOM=1;for i in `seq $n`;do inp="$inp $a";a=$((a+=RANDOM%1000));done
 ulimit -t10 -v1048576;time ./a<<<"$inp"
done

n = 776 লাগে 6.2 সেকেন্ড, n = 891 লাগে 12 সেকেন্ড

n = 1176 লাগে 5.9 এস, এন = 1351 10 এর বেশি সময় নেয়

n = 1351 নেয় 8.7s, n = 1552 10 এর বেশি লাগে (k = 2 * n / 3 সহ) আমার উপর Intel(R) Core(TM) i3-2375M CPU @ 1.50GHz


2
আমি মনে করি এটি কোড-গল্ফ নয়?
ব্যবহারকারী 202729

@ ব্যবহারকারী202729 এটি আমি সাধারণত সি কোড - ইনকনাবুলাম- স্টাইল লিখি ।
এনজিএন

@ngn আমি আপনাকে ধরে নিই তবে সাধারণত সাধারণত কোনও ধরণের সিনট্যাক্স হাইলাইট ব্যবহার করবেন না?
জোনাথন ফ্রেচ 23

@ জোনাথনফ্রেচ আমি আসলেই করি। আমি কাস্টমাইজ করেছি আমার syntax/c.vim
এনজিএন

2
@ কোল এটি কেবল নিয়মিত সি, কেবলমাত্র কম। আপনি যদি ভাষাটির সাথে পরিচিত হন তবে আপনি বেশ অসুবিধা ছাড়াই এটি পড়তে সক্ষম হবেন, যদিও বেশ কয়েকবার ধীর হলেও, এখানে একটি লাইনে তথ্য রয়েছে বেশিরভাগ সি প্রোগ্রামাররা 5-10 লাইনে ছড়িয়ে দেবে (কী অপচয়!)। আমি শুধুমাত্র কৌশলযুক্ত বিটের জন্য মন্তব্য লিখেছিলাম।
এনজিএন

3

সি ++, স্কোর = 53

সমাধানটি আমি মন্তব্যে বলেছিলাম। O(n²×k)। (এখন আমি এটি মুছে ফেলেছি কারণ এটি আর প্রয়োজন হয় না) সম্ভবত এটি হ্রাস করা যেতে পারেO(n×k)

ইনপুটটি বেশ নমনীয়, প্রথম লাইনে, প্রথম সংখ্যাটি হ'ল k, অন্য সংখ্যাগুলি অ্যারের আইটেম হয় aতবে এটি যদি কোনও ঘনিষ্ঠ-প্রথম বন্ধনীগুলির মুখোমুখি হয় তবে এটি ইনপুট পড়া বন্ধ করে দেয়। সুতরাং ইনপুট মত K = 1, A = [0, 2, 4, 6, 8] : 12গৃহীত হয়।

// /codegolf/149029/build-an-electrical-grid

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <climits>

bool read(std::istream& str, int& x) {

    char ch;

    do {
        if (str >> x) return true;
        if (str.eof()) return false;
        str.clear(); // otherwise it's probably int parse error
    } while (str >> ch && ch != ']' && ch != ')' && ch != '}');
    // ignore 1 character, but treat any close parentheses as end of input

    // cannot read anything now
    return false;
}

int main() {
    int k; std::vector<int> a;

    //{ Read input
    std::string st; std::getline(std::cin, st);
    std::stringstream sst (st);

    read(sst, k);

    int x;
    while (read(sst, x)) a.push_back(x);
    //}

    std::vector<std::vector<int>> dp (a.size(), std::vector<int>(k));
    // dp[n][k] = min distance you can get for cities [n..a.size()-1]
    // and [k+1] power plants, and city [n] has a power plant.

    // sum_array[x] = sum of coordinates of cities [x..a.size()-1]
    std::vector<int> sum_array (a.size()+1);
    sum_array.back() = 0;
    for (int n = a.size(); n --> 0;)
        sum_array[n] = sum_array[n+1] + a[n];

    for (int n = a.size(); n --> 0;) {
        for (int k1 = k; k1 --> 0;) {
            if (k1 == 0) {
                int nWire = a.size() - 1 - n;
                dp[n][k1] = sum_array[n+1] - nWire * a[n];
            } else {
            // unindent because my screen width is limited

dp[n][k1] = INT_MAX / 2; // avoid stupid overflow error (in case of -ftrapv)

// let [n1] be the next position for a power plant
int first_connect_right = n; // < lengthy variable name kills screen width
// ^ lengthy comment kills screen width

for (int n1 = n + 1; n1 < (int)a.size(); ++n1) {

    while (a[first_connect_right]-a[n] < a[n1]-a[first_connect_right]) ++first_connect_right;

    int nRightWire = n1 - first_connect_right, nLeftWire = first_connect_right - 1 - n;
    dp[n][k1] = std::min(dp[n][k1],
        a[n1]*nRightWire-(sum_array[first_connect_right]-sum_array[n1]) +
        (sum_array[n+1]-sum_array[first_connect_right])-a[n]*nLeftWire +
        dp[n1][k1-1]
    );

}

            }

        }
    }

    int ans = INT_MAX;
    for (int n = a.size()+1-k; n --> 0;) {
        ans = std::min(ans, dp[n].back() + a[n]*n-sum_array[0]+sum_array[n]);
    }

    std::cout << ans << '\n';

    return 0;
}

এটি অনলাইন চেষ্টা করুন!

এলোমেলো পরীক্ষার কেস তৈরি করুন। (ইনপুট Nএবং allyচ্ছিকভাবে শহর পরিসর, 1000×Nডিফল্ট হিসাবে)


যদি এটি কোনও বৃহত্তর পরীক্ষার কেস সমাধান করতে সক্ষম হয় তবে আমি প্রয়োজনীয় intএসকে এস তে পরিবর্তন করব int64_t
ব্যবহারকারী 202729

dp [runned_n, runned_k] = min {dp [runned_n-x, runned_k] + f [x, n]}, সুতরাং সরাসরি ডায়নামিক প্রোগ্রামিং হ'ল ও (এন ^ 2 * কে)। জটিলতা হ্রাস করার জন্য পুরোপুরি উপায় পরিবর্তন করার দরকার আছে?
l4m2

@ l4m2 অ্যালগরিদমটি খারাপ করবেন না! (ভাল, অনুগ্রহের মেয়াদ শেষ হয়নি)
ব্যবহারকারী 202729

দুঃখিত, তবে আমি আপনার "লুণ্ঠন" অর্থ "ফেলে দেওয়া" বা "চুরি" বা উভয়ই যথেষ্ট জানি না। উভয় অর্থ খুঁজে পেতে পারেন। আমি এই শব্দটি বেশ জানি না। (আমি ভেবেছি অনুগ্রহের অর্থ আবদ্ধ)
l4m2

2
প্রশ্নটি উল্লেখ করে এলোমেলো পরীক্ষার জেনারেটর একটি [0] = 0 প্রয়োগ করে না।
অ্যান্ডারস ক্যাসরগ

2

সি #, স্কোর = 23

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

using Combinatorics.Collections;
using System;

namespace ElectricalGrid
{
    class Program
    {
        static void Main(string[] args)
        {
            if (Build(1, new long[] { 0, 2, 4, 6, 8 }) == 12)
                Console.WriteLine("OK");
            else
                Console.WriteLine("ERROR");
            if (Build(3, new long[] { 0, 1, 10, 11, 20, 21, 22, 30, 32 }) == 23)
                Console.WriteLine("OK");
            else
                Console.WriteLine("ERROR");
            if (Build(5, new long[] { 0, 1, 3, 6, 8, 11, 14 }) == 3)
                Console.WriteLine("OK");
            else
                Console.WriteLine("ERROR");
            if (Build(6, new long[] { 0, 1, 3, 6, 8, 14, 15, 18, 29, 30, 38, 41, 45, 46, 49, 58, 66, 72, 83, 84 }) == 49)
                Console.WriteLine("OK");
            else
                Console.WriteLine("ERROR");

            Console.ReadKey();
        }

        static long Build(int k, long[] a)
        {
            var combs = new Combinations<long>(a, k);
            var totalDist = long.MaxValue;
            foreach (var c in combs)
            {
                long tempDist = 0;
                foreach (var i in a)
                {
                    var dist = long.MaxValue;
                    foreach (var e in c)
                    {
                        var t = Math.Abs(i - e);
                        if (t < dist) dist = t;
                    }
                    tempDist += dist;
                }
                if (tempDist < totalDist) totalDist = tempDist;
            }
            return totalDist;
        }
    }
}

সত্যই সহজ ব্যাখ্যা: উপাদানগুলির প্রতিটি সংমিশ্রণের cজন্য , প্রতিটি উপাদান থেকে নিকটতম উপাদানের দূরত্বগুলির যোগফল গণনা করুনkaac , এবং অন্তত মোট দূরত্ব সঙ্গে একযোগে ফিরে যান।

Buildপদ্ধতির এক-লাইন সংস্করণ (সম্ভবত সম্ভবত মূল, প্রসারিত সংস্করণের চেয়ে ধীরে ধীরে; এটিতে একটি উল্লেখ যুক্ত করা দরকার System.Linq):

static long Build(int k, long[] a)
{
    return new Combinations<long>(a, k).Min(c => a.Sum(i => c.Min(e => Math.Abs(i - e))));
}

2

সি ++, স্কোর = 48

#include <stdio.h>
#include <queue>
#include <algorithm>
typedef long long ull;
typedef unsigned int uint;
uint A[1<<20];
ull S[1<<20];

double ky = 1;
struct point {
    ull dist;
    int n;
    inline point() {}
    inline point(ull dist, int n): dist(dist), n(n) {}
    inline double res() const{
        return dist + n * ky;
    }
    inline int operator<(const point& other) const {
        return res() < other.res();
    }
} V[1<<20];
inline ull f(int L, int R) {
    int m = L+R+1 >> 1;
    return (S[R]-S[m]) - A[m]*(R-m) +
           A[m]*(m-L) - (S[m]-S[L]);
}
int main() {
    int N, K, i, j, p;
    scanf ("%d%d", &N, &K);
    ull s = 0;
    for (i=1; i<=N; i++) {
        scanf ("%u", A+i);
        S[i] = s += A[i];
    }
    double kyL = 0, kyH = 1e99;
    point cL, cR;
    for (int step=0; step++<50; ky = std::min(ky*2, (kyL+kyH)*.5)) {
        for (i=1; i<=N; i++) {
            point tmp(f(0,i), 1);
            for (j=1; j<i; j++) {
            //printf("ky=%f [%d]=%d %I64d %f\n", ky, i, tmp.n, tmp.dist, tmp.res());
                point cmp = V[j];
                cmp.dist += f(j, i);
                cmp.n ++;
                if (cmp<tmp) tmp=cmp;
            }
            //printf("ky=%f [%d]=%d %I64d %f\n", ky, i, tmp.n, tmp.dist, tmp.res());
            V[i] = tmp;
        }
        if (V[N].n == K) {
_:          return! printf("%I64d", V[N].dist);
        }
        if (V[N].n > K) {
            kyL = ky;
            cL = V[N];
        } else {
            kyH = ky;
            cR = V[N];
        }
        //printf("ky=%f %d %I64d %f\n", ky, V[N].n, V[N].dist, V[N].res());
        //getch();
    }
    V[N].dist = (double)cL.dist / (cR.n-cL.n) * (K-cL.n) +
                (double)cR.dist / (cL.n-cR.n) * (K-cR.n) + .5;
    printf("%I64d", V[N].dist);
}

ব্যবহারের ইনপুট: এনকেএ [1] এ [2] ... এ [এন]


2
তোমাদের মধ্যে সীমা বৃদ্ধি করি তাহলে step70, তারপর আপনার pretest স্কোর 60 হয়
Colera সু


2

জাভাস্ক্রিপ্ট (ES6) (নোড.জেএস) , স্কোর = 10

নতুন অ্যালগরিদম, এটি যদি এইবার আসলে কাজ করে তা ব্যাখ্যা করবে।

const {performance} = require('perf_hooks');

class Connection{
    constructor(left,index,length,right){
        if(typeof right === 'undefined'){
            this._distance = 0;
        } else {
            this._distance = typeof left === 'undefined' ? 0 :
                    Math.abs(right - left);
        }
        var half = Math.floor(length/2);
        if(length % 2 < 1){
            this._magnitude = half - Math.abs(index - half + 1);
        } else {
            var temp = index - half;
            this._magnitude = half - Math.abs(temp >= 0 ?temp:temp + 1);
        }
        this._value = this.distance * this.magnitude;
    }

    get distance(){return this._distance;};
    get magnitude(){return this._magnitude;};
    set magnitude(value){
        this._magnitude = value;
        this._value = this.distance * this.magnitude;
    };
    valueOf(){return this._value};
}

class Group{
	constructor(...connections){
        this._connections = connections;
		
		this._max = Math.max(...connections); //uses the ValueOf to get the highest Distance to the Left
	}
	get connections(){return this._connections;};
	get max(){return this._max;};
    cutLeft(index){

            for(let i=1,j=index-1;;i++){
                
                if(typeof this.connections[j] === 'undefined' || this.connections[j].magnitude <= i){
                    break;
                }
                this.connections[j].magnitude = i;
                j--;
            }

    }

    cutRight(index){

            for(let i=0,j=index;;i++){
                
                if(typeof this.connections[j] === 'undefined' || this.connections[j].magnitude <= i){
                    break;
                }
                this.connections[j].magnitude = i;
                j++;
            }

    }

    static of(...connections){
        return new Group(...connections.map((c,i)=>new Connection(c.distance,i,connections.length)));
    }

	split(){
        var index = this.connections.findIndex(c=>c.valueOf() == this.max);
        if(index < 0){
            return;
        }
        var length = this.connections.length;
        var magnitude = this.connections[index].magnitude;

        this.cutLeft(index);
        this.cutRight(index);
        this._max = Math.max(...this.connections);
	}

    center(){
        if(typeof this._center === 'undefined'){
            this._center = this.connections.reduce((a,b)=>a==0?b.valueOf():a.valueOf()+b.valueOf(),0);
        }
        return this._center;
    }

    valueOf(){return this._max;};
    toString(){
        var index = this.connections.findIndex(c=>c.valueOf() == this.max);
        var value = this.connections[index].magnitude;
        var ret = '';
        for(let i = 0;i<value;i++){
            ret += this.connections.map(c=>{return (i<c.magnitude)?c.distance:' ';}).reduce((a,b)=>a==''?b:a+'-'+b,'') + '\n';
        }
        return ret;
    };
}

function crunch(plants, cities){
	var found = [];
    var size = cities.length;
    cities = cities.map((city,i,arr)=> new Connection(city,i,size,arr[i+1])).slice(0,cities.length-1);
    var group = new Group(...cities);
    for(;plants>1;plants--){
    group.split();
    }
    console.log(`Wire Length Needed: ${group.center()}`);
}

function biggestGroup(groups){
	return groups.find(g => g[g.length-1].orig - g[0].orig);
}

function* range (start, end, limit) {
    while (start < end || typeof limit !== 'undefined' && limit-- > 0) {
        yield start
        start += 1 + Math.floor(Math.random()*100);
    }
}

function* cities (score){
	let n = Math.floor(Math.pow(2,score/5));
	var start = 0;
	while (n-- > 0 && start <= (1000 * n)) {
		yield start;
        start += 1 + Math.floor(Math.random()*100);
    }
}


if(typeof process.argv[3] === 'undefined'){
    crunch(1,[0, 2, 4, 6, 8]);
    console.log("Correct Answer: 12");
    crunch(3,[0, 1, 10, 11, 20, 21, 22, 30, 32]);
    console.log("Correct Answer: 23");
    crunch(5,[0, 1, 3, 6, 8, 11, 14]);
    console.log("Correct Answer: 3");
    crunch(6,[0, 1, 3, 6, 8, 14, 15, 18, 29, 30, 38, 41, 45, 46, 49, 58, 66, 72, 83, 84]);
    console.log("Correct Answer: 49");
    crunch(2, [0, 21, 31, 45, 49, 54]);
    console.log("Correct Answer: 40");
    crunch(2, [0, 4, 7, 9, 10]);
    console.log("Correct Answer: 7");
    crunch(2, [0, 1, 3, 4, 9]);
    console.log("Correct Answer: 6");
    
    var max = 0;
    var min = Number.POSITIVE_INFINITY;
    var avg = [];
    
    var score = typeof process.argv[2] === 'undefined' ? 60 : process.argv[2];

    for(j = 0; j<10; j++){
        var arr = []; for(let i of cities(score)) arr.push(i);
        var plants = Math.floor(1 + Math.random() * arr.length);
        console.log(`Running: Test:${j} Plants: ${plants}, Cities ${arr.length}, Score: ${score}`);
        // console.log(`City Array: [${arr}]`);
        var t0 = performance.now();
        crunch(plants,arr);
        var t1 = performance.now();
        time = (t1-t0)/1000;
        console.log(`Time Taken = ${time} seconds`);
        avg.push(time);
        max = Math.max(time,max);
        min = Math.min(time,min);
    }
    console.log(`Bench: ${avg.reduce((a,b)=>a+b,0)/avg.length} Max: ${max} Min: ${min} Total: ${avg.reduce((a,b)=>a+b,0)}`);
} else {
    var plants = process.argv[2];
    var arr = process.argv.slice(3);
    console.log(`Running: Plants: ${plants}, Cities ${arr.length}`);
    var t0 = performance.now();
    crunch(plants,arr);
    var t1 = performance.now();
    time = (t1-t0)/1000;
    console.log(`Time Taken = ${time} seconds`);
}

এটি অনলাইন চেষ্টা করুন!

অন্যটির মতো একইভাবে চালান।

জাভাস্ক্রিপ্ট (ES6) (নোড.জেএস) , প্রিস্টেট স্কোর = 12 12

অ্যালগরিদমের রূপরেখা:

প্রোগ্রামটি প্রথমে সিটি ক্লাসে ডেটা ম্যাপ করে, যা কয়েকটি ডেটা পয়েন্ট ম্যাপ করে:

  • শহর - শহরের পরম দূরত্ব
  • বাম - বাম নিকটতম শহরের দূরত্ব
  • ডান - নিকটতম শহর থেকে ডানদিকে দূরত্ব
  • সূচক - (মূলত শহর অ্যারেতে সূচিত) সূচক

অ্যারেটি তখন গ্রুপ ক্লাসে নিক্ষেপ করা হয়, যার নিম্নলিখিতটি রয়েছে:

  • শহর - শহর অ্যারে
  • দূর - গ্রুপ বিস্তৃত দূরত্ব
  • সর্বাধিক - গ্রুপের বৃহত্তম বাম সংযোগ
  • বিভক্ত ()
    • গ্রুপের কেন্দ্রের শহরের সাথে সংযোগযুক্ত বৃহত্তম সংযোগের সাথে উপগোষ্ঠী বিভক্ত একটি অ্যারে প্রদান করে
    • যদি 2 টি কেন্দ্র নোড থাকে (একটি দৈর্ঘ্যের গ্রুপ) তবে এটি 3 টি সংযোগ থেকে চয়ন করে choo
    • (* দ্রষ্টব্য *: এটি দুটি শহরেরও কম সংখ্যক গ্রুপকেই ফেলে দেবে)
  • কেন্দ্র ()
    • গোষ্ঠীর জন্য সেরা তারের মান প্রদান করে
    • এই পদক্ষেপের জন্য ছেড়ে যাওয়া প্রতিটি শহরে পুনরাবৃত্তি ছেড়ে যাওয়ার সমাধানে কাজ করা
    • এখন 50% কম ম্যাপিং সহ

এখন অ্যালগরিদম যতক্ষণ না 2 বা ততোধিক পাওয়ার প্ল্যান্ট রাখে ততক্ষণ গ্রুপগুলিকে বিভক্ত করতে এগিয়ে যায়।

শেষ পর্যন্ত এটি দলগুলিকে এর কেন্দ্রগুলিতে ম্যাপ করে এবং এগুলি সমস্ত সংখ্যার যোগফল দেয়।

কীভাবে চালাবেন:

নোড.জেএস ব্যবহার করে চালান (v9.2.0 যা সৃষ্টির জন্য ব্যবহৃত হয়েছিল)

স্কোর 70 এর জন্য উত্পন্ন পরীক্ষার কেসগুলি ব্যবহার করে প্রোগ্রামটি চালাচ্ছেন:

node program.js 70

1 টি বিদ্যুৎ কেন্দ্র এবং শহরগুলি [0,3,5] ব্যবহার করে প্রোগ্রামটি চালাচ্ছে:

node program.js 1 0 3 5

কোড:

const {performance} = require('perf_hooks');

class City{
	constructor(city, left, right, i){
		this._city = city;
		this._index = i;
		this._left = typeof left === 'undefined' ? 0 : city - left;
		this._right = typeof right === 'undefined' ? 0 : right - city;
	}

	get city(){return this._city;};
	get index(){return this._index;};
	get left(){return this._left;};
    get right(){return this._right;};
    set left(left){this._left = left};
    set right(right){this._right = right};

	valueOf(){return this._left;};
}

class Group{
	constructor(...cities){
        this._cities = cities;
        // console.log(cities.map(a=>a.city).reduce((a,b)=>a===''?a+(b<10?' '+b:b):a+'-'+(b<10?' '+b:b),""));
        // console.log(cities.map(a=>a.left).reduce((a,b)=>a===''?a+(b<10?' '+b:b):a+'-'+(b<10?' '+b:b),""));
        // console.log(cities.map(a=>a.right).reduce((a,b)=>a===''?a+(b<10?' '+b:b):a+'-'+(b<10?' '+b:b),""));
        // console.log("+==+==+==+==+==+==+==+==+==+==+==+==")
		this._dist = cities[cities.length-1].city - cities[0].city;
		this._max = Math.max(...cities); //uses the ValueOf to get the highest Distance to the Left
	}

	get dist(){return this._dist;};
	get cities(){return this._cities;};
	get max(){return this._max;};

	split(){
        //var index = this.cities.findIndex(city=>city.left == this.max);
        //this.cities[index].left = 0;
        // console.log(`Slicing-${this.max}-${index}------`)
        var centerIndex = this.cities.length / 2;
        var splitIndex = Math.floor(centerIndex);
        if(centerIndex%1 > 0){
            var center = this.cities[splitIndex];
            if(center.right > center.left){

                splitIndex++;
            }
        } else {
            var right = this.cities[splitIndex];
            var left = this.cities[splitIndex-1];
            if(left.left > Math.max(right.right,right.left)){
               
                splitIndex--;
            } else if(right.right > Math.max(left.left,left.right)){
                
                splitIndex++;
            }
        }
        // console.log(splitIndex);
        this.cities[splitIndex].left = 0;
        this.cities[splitIndex-1].right = 0;
        var leftCities = [...this.cities.slice(0,splitIndex)];
        var rightCities = [...this.cities.slice(splitIndex)];

        // var center = this.cities[]

        if(leftCities.length <= 1){
            if(rightCities.length <= 1){
                return [];
            }
            return [new Group(...rightCities)]
        }
        if(rightCities.length <= 1){
            return [new Group(...leftCities)];
        }
        return [new Group(...leftCities), new Group(...rightCities)];
	}

    center(){
        if(typeof this._center === 'undefined'){
            if(this.cities.length == 1){
                return [0];
            }
            if(this.cities.length == 2){
                return this.cities[1].left;
            }
            var index = Math.floor(this.cities.length/2);
            this._center = this.cities.reduce((a,b)=> {
                // console.log(`${a} + (${b.city} - ${city.city})`);
                return a + Math.abs(b.city - this.cities[index].city);
            },0);
            // console.log(this._center);
        }
        
        return this._center;
    }

	valueOf(){return this._max;};
}

function crunch(plants, cities){
	var found = [];
    var size = cities.length;
    cities = cities.map((city,i,arr)=> new City(city,arr[i-1],arr[i+1],i));
	var groups = [new Group(...cities)];

	// console.log(groups);
    for(;plants>1;plants--){
        var mapped = groups.map(g=>g.center()-g.max);
        var largest = Math.max(...groups);
        // console.log('Largest:',largest)
        // console.log(...mapped);
		var index = groups.findIndex((g,i)=> mapped[i] == g.center() - g.max && g.max == largest);
		// console.log(index);
        groups = index == 0 ? 
            [...groups[index].split(),...groups.slice(index+1)]:
            [...groups.slice(0,index),...groups[index].split(),...groups.slice(index+1)];
    }
    // console.log(`=Cities=${size}================`);
    // console.log(groups);
    size = groups.map(g=>g.cities.length).reduce((a,b)=>a+b,0);
    
    // console.log(`=Cities=${size}================`);
    var wires = groups.map(g=>g.center());
    
    // console.log(...wires);
    // console.log(`=Cities=${size}================`);
    console.log(`Wire Length Needed: ${wires.reduce((a,b)=>a + b,0)}`);
}

function biggestGroup(groups){
	return groups.find(g => g[g.length-1].orig - g[0].orig);
}

function* range (start, end, limit) {
    while (start < end || typeof limit !== 'undefined' && limit-- > 0) {
        yield start
        start += 1 + Math.floor(Math.random()*100);
    }
}

function* cities (score){
	let n = Math.floor(Math.pow(2,score/5));
	var start = 0;
	while (n-- > 0 && start <= (1000 * n)) {
		yield start;
        start += 1 + Math.floor(Math.random()*100);
    }
}

if(typeof process.argv[3] === 'undefined'){
    crunch(1,[0, 2, 4, 6, 8]);
    console.log("Correct Answer: 12");
    crunch(3,[0, 1, 10, 11, 20, 21, 22, 30, 32]);
    console.log("Correct Answer: 23");
    crunch(5,[0, 1, 3, 6, 8, 11, 14]);
    console.log("Correct Answer: 3");
    crunch(6,[0, 1, 3, 6, 8, 14, 15, 18, 29, 30, 38, 41, 45, 46, 49, 58, 66, 72, 83, 84]);
    console.log("Correct Answer: 49");
    crunch(2, [0, 21, 31, 45, 49, 54]);
    console.log("Correct Answer: 40");
    crunch(2, [0, 4, 7, 9, 10]);
    console.log("Correct Answer: 7");
    
    var max = 0;
    var min = Number.POSITIVE_INFINITY;
    var avg = [];
    
    var score = typeof process.argv[2] === 'undefined' ? 60 : process.argv[2];

    for(j = 0; j<10; j++){
        var arr = []; for(let i of cities(score)) arr.push(i);
        var plants = Math.floor(1 + Math.random() * arr.length);
        console.log(`Running: Test:${j} Plants: ${plants}, Cities ${arr.length}, Score: ${score}`);
        var t0 = performance.now();
        crunch(plants,arr);
        var t1 = performance.now();
        time = (t1-t0)/1000;
        console.log(`Time Taken = ${time} seconds`);
        avg.push(time);
        max = Math.max(time,max);
        min = Math.min(time,min);
    }
    console.log(`Bench: ${avg.reduce((a,b)=>a+b,0)/avg.length} Max: ${max} Min: ${min} Total: ${avg.reduce((a,b)=>a+b,0)}`);
} else {
    var plants = process.argv[2];
    var arr = process.argv.slice(3);
    console.log(`Running: Plants: ${plants}, Cities ${arr.length}`);
    var t0 = performance.now();
    crunch(plants,arr);
    var t1 = performance.now();
    time = (t1-t0)/1000;
    console.log(`Time Taken = ${time} seconds`);
}

এটি অনলাইন চেষ্টা করুন!

আমি মন্তব্য করা কোডটি পরবর্তী কয়েক দিনের মধ্যে পরিষ্কার করব যেহেতু আমি এখনও এটি নিয়ে কাজ করছি, কেবল এটি দেখতে চেয়েছিলাম যে এটি কেবল ছোট ছোট মামলার চেয়ে বেশি পার করছে কিনা।


টেস্টকেস বিবেচনা করুন K = 2, A = [0, 21, 31, 45, 49, 54]। সঠিক উত্তরের 40, কিন্তু আপনার প্রোগ্রাম 51. আউটপুট
Colera সু

এমনকি সহজ: K = 2, A = [0, 4, 7, 9, 10]। সঠিক: 7, আপনার উত্তর: 8
কোলেরা সু

ঠিক আছে এটি এখন কাজ করা উচিত ... এটি কমপক্ষে সমস্ত প্রদত্ত কেসগুলির জন্য কাজ করে।
উইলসন জনসন রিটা 232

আসলে আমি আরও একটি অ্যালগরিদমও উত্পন্ন করতে পারি যা আরও ভাল কাজ করে। আমি তত্ত্বটি পরীক্ষা করতে যাচ্ছি এবং এটি কিছুটা পোস্ট করব।
উইলসন জনসন রিটা 232

এখনও কাজ করছে না ... K = 2, A = [0, 1, 3, 4, 9]। সঠিক: 6, আপনার উত্তর: 7।
কলেরা সু

1

সি (প্রতিযোগিতামূলক, প্রিস্টেট স্কোর = 76)

@ AndersKaseorg এর দ্বিতীয় মরিচ সমাধানটি সি এর কাছে অনুবাদ করার চেষ্টা এটি is

typedef void V;typedef char C;typedef long L;
#define R return
#define W while
#define S static
#include<sys/syscall.h>
#define exit(x)     ({L r;asm volatile("syscall":"=a"(r):"0"(SYS_exit ),"D"(x)              :"cc","rcx","r11","memory");r;})
#define read(x,y,z) ({L r;asm volatile("syscall":"=a"(r):"0"(SYS_read ),"D"(x),"S"(y),"d"(z):"cc","rcx","r11","memory");r;})
#define write(x,y,z)({L r;asm volatile("syscall":"=a"(r):"0"(SYS_write),"D"(x),"S"(y),"d"(z):"cc","rcx","r11","memory");r;})
S V P(L x){C s[32],*p=s+32;*--p='\n';do{*--p='0'+x%10;x/=10;}W(x);write(1,p,s+32-p);}
#define N 0x100000 //max
#define INF (-1ul>>1)
S L cost[N],nk1,*am; //nk1:n-k+1, am:input's partial sums offset with the current "m" in _start()
S L f(L i,L j){if(i+1>=j&&cost[j]!=INF){L h=(i-j+1)>>1;R cost[j]+am[i+1]-am[j+h]-am[i-h+1]+am[j];}else{R INF;}}
S V smawk(L sh,L*c,L nc,L*r){ //sh:shift,c:cols,r:result
 L n=nk1>>sh;if(!n)R;
 L m=n>>1,u[m];
 if(n<nc){
  L ns=0,s[nc],sk[nc],*skp=sk;
  for(L jk=0;jk<nc;jk++){
   L j=c[jk];W(ns>0&&f(~(~(ns-1)<<sh),j)<=f(~(~(ns-1)<<sh),s[ns-1])){--ns;--skp;}
   if(ns<n){s[ns++]=j;*skp++=jk;}
  }
  smawk(sh+1,s,ns,u);for(L i=0;i<m;i++)u[i]=sk[u[i]];
 }else{
  smawk(sh+1,c,nc,u);
 }
 L l=0,ish=(1<<sh)-1,dsh=1<<(sh+1);
 for(L i=0;i<m;i++){
  L k=u[i],bj=l,bc=f(ish,c[l]);
  for(L j=l+1;j<=k;j++){L h=f(ish,c[j]);if(h<bc){bc=h;bj=j;}}
  *r++=bj;*r++=k;l=k;ish+=dsh;
 }
 if(n&1){
  L nsh=~(~(n-1)<<sh),bj=l,bc=f(nsh,c[l]);
  for(L j=l+1;j<nc;j++){L h=f(nsh,c[j]);if(h<bc){bc=h;bj=j;}}
  *r=bj;
 }
}
S L inp(L*a){
 L n=-1,l,v=0;C b[1<<20];
 W(0<(l=read(0,b,sizeof(b))))for(L i=0;i<l;i++)if('0'<=b[i]&&b[i]<='9'){v=b[i]-'0'+10*v;}else{a[++n]=v;v=0;}
 R n;
}
V _start(){
 S L a[N];L n=inp(a),k=*a,s=0;for(L i=0;i<n;i++){a[i]=s;s+=a[i+1];}a[n]=s;
 *cost=0;for(L i=1,l=n+1-k;i<l;i++)cost[i]=INF;
 S L c[N];L nc=n+1-k;for(L i=0;i<nc;i++)c[i]=i;
 S L r[N];nk1=n-k+1;for(L m=0;m<k;m++){am=a+m;smawk(0,c,nc,r);for(L i=n-k;i>=0;i--)cost[i]=f(i,r[i]);}
 P(cost[n-k]);exit(0);
}

এর সাথে সংকলন:

#!/bin/bash -e
clang -O3 -nostdlib -ffreestanding -fno-unwind-tables -fno-unroll-loops -fomit-frame-pointer -oa a.c
strip -R.comment -R'.note*' a

1

পরিষ্কার , স্কোর = 65

module main
import StdEnv, System.IO

parseArgs :: *World -> ((Int, {#Int}), *World)
parseArgs world
    # (args, world)
        = nextArgs [] world
    # args
        = reverse args
    # (k, a)
        = (hd args, tl args)
    = ((toInt k, {toInt n \\ n <- a}), world)
where
    nextArgs :: [String] *World -> ([String], *World)
    nextArgs args world
        # (arg, world)
            = evalIO getLine world
        | arg == ""
            = (args, world)
        = nextArgs [arg:args] world

minimalWeight :: Int !{#Int} -> Int
minimalWeight k a
    # count
        = size a
    # touches
        = createArray ((count - k + 3) / 2 * k) 0
    = treeWalk k count a [(0, 0, 0, 0)] touches
where
    treeWalk :: Int !Int {#Int} ![(!Int, !Int, Int, Int)] *{Int} -> Int
    treeWalk k verticies a [(weight, vertex, degree, requires) : nodes] touches
        | vertex >= verticies
            = weight
        | requires >= k
            = treeWalk k verticies a nodes touches
        # index
            = degree * k + requires
        | (select touches index) > vertex
            = treeWalk k verticies a nodes touches
        # (next, pivot)
            = (vertex + 1 + degree, verticies + requires)
        # (nodes, touches)
            = (orderedPrepend (weight, next, 0, requires + 1) nodes, update touches index (vertex + 1))
        | pivot >= k + next
            # (weight, vertex)
                = (weight + (select a next) - (select a vertex), vertex + 1)
            # nodes
                = orderedPrepend (weight, next + 1, 0, requires + 1) nodes
            | pivot == k + next
                = treeWalk k verticies a nodes touches
            # weight
                = weight + (select a (next + 1)) - (select a vertex)
            # nodes
                = orderedPrepend (weight, vertex, degree + 1, requires) nodes
            = treeWalk k verticies a nodes touches
        = treeWalk k verticies a nodes touches
    where
        orderedPrepend :: (!Int, Int, Int, Int) ![(!Int, Int, Int, Int)] -> [(Int, Int, Int, Int)]
        orderedPrepend a []
            = [a]
        orderedPrepend a [b : b_]
            # (x, _, _, _)
                = a
            # (y, _, _, _)
                = b
            | y > x
                = [a, b : b_]
            = [b : orderedPrepend a b_]

Start world
    # ((k, a), world)
        = parseArgs world
    = minimalWeight k a

এর সাথে সংকলন:
clm -h 1024M -gci 32M -gcf 32 -s 32M -t -nci -ou -fusion -dynamics -IL Platform main

কমান্ড-লাইন আর্গুমেন্ট হিসাবে Kএবং এর পরে প্রতিটি উপাদান নেয় A


@ কলেরাশু আমি জিজ্ঞাসা করতে পারি যে স্কোরের সিদ্ধান্তের কারণটি কী ছিল? সঠিকতা / সময় / স্মৃতি? আমি আশা করি এটি সময় ছিল
24urous

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