Submission #51080044


Source Code Expand

def main
    t = str
    n= int
    a = []
    n.times do |i|
        a << strary
        a.last.shift
    end
    dp = [{}]
    renketu = ""
    # t.each do |i|
    #     renketu += i
    #     dp[0][renketu] = 0
    # end
    # pp dp
    dp = Array.new(n, {})
    dp = [{"" => 0}]
    a.each.with_index do |v, i|
        dp[i + 1] = dp[i].dup
        v.each do |j|
            dp[i].each do |k|
                next unless t.start_with?("#{k[0]}#{j}")
                if dp[i+1][k[0]+j] == nil
                    dp[i+1][k[0]+j] = dp[i][k[0]] + 1
                else
                    dp[i+1][k[0]+j] = [dp[i+1][k[0]+j], dp[i+1][k[0]] + 1].min
                end
            end
        end
    end
    if dp[n][t] == nil
        puts -1
    else
        puts dp[n][t]
    end
end

#----------------------------------------------------------------------------------
require "set"
def int
    gets.chomp.to_i
end

def intary
    gets.chomp.split(" ").map(&:to_i)
end

def str
    gets.chomp
end

def strary
    gets.chomp.split(" ")
end

def is_lower?(c)
    c != c.upcase
end

def grouping(ary)
    ary.slice_when { |a, b| a != b }.to_a
end

def number?(str)
nil != (str =~ /\A[0-9]+\z/)
end

# 階乗
def factorial(n, bottom=1)
    n == 0 ? 1 : (bottom..n).inject(:*)
end

# nCr
def nCr(n, r)
    factorial(n) / (factorial(r) * factorial(n-r))
end

def make_tree(n, path, way = false)
    if n != 0
        tree = {}
        path.times do |i|
            u,v = intary
            tree[u] ? tree[u] << v : tree[u] = v
            if way
                tree[v] ? tree[v] << u : tree[v] = u
            end
        end
    else
        tree = Array.new(n+1) {Array.new}
        path.times do |i|
            u,v = intary
            tree[u] << v
            if way
                tree[v] << u
            end
        end
    end
    return tree
end

def make_visited(n)
    Array.new(n+1, false)
end

def make_map(n, type)
    map = []
    if type == "s"
        n.times do |i|
            map << strary
        end
    elsif type == "i"
        n.times do |i|
            map << intary
        end
    end
    return map
end

def nisinsu(int)
    return int.to_s(2).chomp
end

def zeroume(keta, int)
    sprintf("%0#{keta}d", int)
end

# 約数列挙
def divisors(n)
    result = []
    
    doit = ->(pd, acc) {
        return if pd.empty?
        x, *xs = pd
        (0..x[1]).each do |i|
            e = acc * x[0] ** i
            result << e
            doit.(xs, e)
        end
    }
    doit.(n.prime_division, 1)
    
    result.uniq.sort
end
# 累積和作成
def ruiseki(arr)
    s = Array.new(arr.size + 1)
    s[0] = 0
    (0...arr.size).each do |i|
        s[i+1] = s[i] + arr[i]
    end
    return s
end
class PriorityQueue
    # By default, the priority queue returns the maximum element first.
    # If a block is given, the priority between the elements is determined with it.
    # For example, the following block is given, the priority queue returns the minimum element first.
    # `PriorityQueue.new { |x, y| x < y }`
    #
    # A heap is an array for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for all k, counting elements from 0.
    def initialize(array = [], &comp)
        @heap = array
        @comp = comp || proc { |x, y| x > y }
        heapify
    end

    attr_reader :heap

    # Push new element to the heap.
    def push(item)
    shift_down(0, @heap.push(item).size - 1)
    end

    alias << push
    alias append push

    # Pop the element with the highest priority.
    def pop
        latest = @heap.pop
        return latest if empty?

        ret_item = heap[0]
        heap[0] = latest
        shift_up(0)
        ret_item
    end

    # Get the element with the highest priority.
    def get
        @heap[0]
    end

    alias top get

    # Returns true if the heap is empty.
    def empty?
        @heap.empty?
    end

    private

    def heapify
        (@heap.size / 2 - 1).downto(0) { |i| shift_up(i) }
    end

    def shift_up(pos)
        end_pos = @heap.size
        start_pos = pos
        new_item = @heap[pos]
        left_child_pos = 2 * pos + 1
    
        while left_child_pos < end_pos
            right_child_pos = left_child_pos + 1
            if right_child_pos < end_pos && @comp.call(@heap[right_child_pos], @heap[left_child_pos])
                left_child_pos = right_child_pos
            end
            # Move the higher priority child up.
            @heap[pos] = @heap[left_child_pos]
            pos = left_child_pos
            left_child_pos = 2 * pos + 1
        end
        @heap[pos] = new_item
        shift_down(start_pos, pos)
    end

    def shift_down(star_pos, pos)
        new_item = @heap[pos]
        while pos > star_pos
            parent_pos = (pos - 1) >> 1
            parent = @heap[parent_pos]
            break if @comp.call(parent, new_item)

            @heap[pos] = parent
            pos = parent_pos
        end
        @heap[pos] = new_item
    end
end
# エラトステネスの篩で素数列挙して高速に素因数分解したい!
# ref: https://atcoder.jp/contests/abc177/editorial/82
class PrimeDivWithSieve
    def initialize(n)
        @sieve = [] # nまでの素数を入れる
        @min_div = {} # keyの値の最小の素因数を入れる
        # 他を篩落とし得る素数はsqrtを上限にできる
        (2..Math.sqrt(n).floor).each do |i|
            next if @min_div[i] # ここに値が入ってる = ふるい落とされている
            @sieve << i # ふるい落とされずに来たらそいつは素数
    
            sieve_target = i * i
            while sieve_target <= n do
            @min_div[sieve_target] ||= i
            sieve_target += i
            end
        end
        (Math.sqrt(n).floor.next..n).each do |i|
            next if @min_div[i]
            @sieve << i
        end
    end
    # Integer#prime_division と同じ値を返すようにする
    # https://docs.ruby-lang.org/ja/latest/method/Integer/i/prime_division.html
    def prime_division(num)
        return num if !@min_div[num] # 素数のときすぐ返す
        return_num = 1 # [[a, x], [b, y]] <=> num = a^x * b^y
        while num > 1 do
            prime = @min_div[num] # 最小の素因数, nil => numが素数
            break return_num *= num if !prime
            div_total = 0
            while num % prime == 0 do
            num /= prime
            div_total += 1
            end
            return_num *= prime  if div_total % 2 != 0
        end
        return_num
    end
    def prime_list
        @sieve
    end
end
HeapQueue = PriorityQueue
main
# def main
#     t = str
#     n = int
#     a = []
#     count = []
#     n.times do |i|
#         a << strary
#         count << a.last.shift
#     end
#     dp = [{}]
#     renketu = ""
#     # t.each do |i|
#     #     renketu += i
#     #     dp[0][renketu] = 0
#     # end
#     # pp dp
#     dp = Array.new(n, {})
#     dp[0][""] = 0
#     a.each.with_index do |v, i|

#         v.each do |j|
#             dp[i].each do |k|
#                 next unless t.start_with?("#{k[0]}#{j}")
#                 if dp[i+1]["#{k[0]}#{j}"] == nil
#                     dp[i+1]["#{k[0]}#{j}"] = dp[i][k[0]] + 1
#                 else
#                     dp[i+1]["#{k[0]}#{j}"] = [dp[i+1]["#{k[0]}#{j}"], dp[i+1][k[0]] + 1].min
#                 end
#             end
#         end
#     end
#     if dp[n][t] == nil
#         puts -1
#     else
#         puts dp[n][t]
#     end
# end

# #----------------------------------------------------------------------------------
# require "set"
# def int
#     gets.chomp.to_i
# end

# def intary
#     gets.chomp.split(" ").map(&:to_i)
# end

# def str
#     gets.chomp
# end

# def strary
#     gets.chomp.split(" ")
# end

# def is_lower?(c)
#     c != c.upcase
# end

# def grouping(ary)
#     ary.slice_when { |a, b| a != b }.to_a
# end

# def number?(str)
# nil != (str =~ /\A[0-9]+\z/)
# end

# # 階乗
# def factorial(n, bottom=1)
#     n == 0 ? 1 : (bottom..n).inject(:*)
# end

# # nCr
# def nCr(n, r)
#     factorial(n) / (factorial(r) * factorial(n-r))
# end

# def make_tree(n, path, way = false)
#     if n != 0
#         tree = {}
#         path.times do |i|
#             u,v = intary
#             tree[u] ? tree[u] << v : tree[u] = v
#             if way
#                 tree[v] ? tree[v] << u : tree[v] = u
#             end
#         end
#     else
#         tree = Array.new(n+1) {Array.new}
#         path.times do |i|
#             u,v = intary
#             tree[u] << v
#             if way
#                 tree[v] << u
#             end
#         end
#     end
#     return tree
# end

# def make_visited(n)
#     Array.new(n+1, false)
# end

# def make_map(n, type)
#     map = []
#     if type == "s"
#         n.times do |i|
#             map << strary
#         end
#     elsif type == "i"
#         n.times do |i|
#             map << intary
#         end
#     end
#     return map
# end

# def nisinsu(int)
#     return int.to_s(2).chomp
# end

# def zeroume(keta, int)
#     sprintf("%0#{keta}d", int)
# end

# # 約数列挙
# def divisors(n)
#     result = []
    
#     doit = ->(pd, acc) {
#         return if pd.empty?
#         x, *xs = pd
#         (0..x[1]).each do |i|
#             e = acc * x[0] ** i
#             result << e
#             doit.(xs, e)
#         end
#     }
#     doit.(n.prime_division, 1)
    
#     result.uniq.sort
# end
# # 累積和作成
# def ruiseki(arr)
#     s = Array.new(arr.size + 1)
#     s[0] = 0
#     (0...arr.size).each do |i|
#         s[i+1] = s[i] + arr[i]
#     end
#     return s
# end
# class PriorityQueue
#     # By default, the priority queue returns the maximum element first.
#     # If a block is given, the priority between the elements is determined with it.
#     # For example, the following block is given, the priority queue returns the minimum element first.
#     # `PriorityQueue.new { |x, y| x < y }`
#     #
#     # A heap is an array for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for all k, counting elements from 0.
#     def initialize(array = [], &comp)
#         @heap = array
#         @comp = comp || proc { |x, y| x > y }
#         heapify
#     end

#     attr_reader :heap

#     # Push new element to the heap.
#     def push(item)
#     shift_down(0, @heap.push(item).size - 1)
#     end

#     alias << push
#     alias append push

#     # Pop the element with the highest priority.
#     def pop
#         latest = @heap.pop
#         return latest if empty?

#         ret_item = heap[0]
#         heap[0] = latest
#         shift_up(0)
#         ret_item
#     end

#     # Get the element with the highest priority.
#     def get
#         @heap[0]
#     end

#     alias top get

#     # Returns true if the heap is empty.
#     def empty?
#         @heap.empty?
#     end

#     private

#     def heapify
#         (@heap.size / 2 - 1).downto(0) { |i| shift_up(i) }
#     end

#     def shift_up(pos)
#         end_pos = @heap.size
#         start_pos = pos
#         new_item = @heap[pos]
#         left_child_pos = 2 * pos + 1
    
#         while left_child_pos < end_pos
#             right_child_pos = left_child_pos + 1
#             if right_child_pos < end_pos && @comp.call(@heap[right_child_pos], @heap[left_child_pos])
#                 left_child_pos = right_child_pos
#             end
#             # Move the higher priority child up.
#             @heap[pos] = @heap[left_child_pos]
#             pos = left_child_pos
#             left_child_pos = 2 * pos + 1
#         end
#         @heap[pos] = new_item
#         shift_down(start_pos, pos)
#     end

#     def shift_down(star_pos, pos)
#         new_item = @heap[pos]
#         while pos > star_pos
#             parent_pos = (pos - 1) >> 1
#             parent = @heap[parent_pos]
#             break if @comp.call(parent, new_item)

#             @heap[pos] = parent
#             pos = parent_pos
#         end
#         @heap[pos] = new_item
#     end
# end
# # エラトステネスの篩で素数列挙して高速に素因数分解したい!
# # ref: https://atcoder.jp/contests/abc177/editorial/82
# class PrimeDivWithSieve
#     def initialize(n)
#         @sieve = [] # nまでの素数を入れる
#         @min_div = {} # keyの値の最小の素因数を入れる
#         # 他を篩落とし得る素数はsqrtを上限にできる
#         (2..Math.sqrt(n).floor).each do |i|
#             next if @min_div[i] # ここに値が入ってる = ふるい落とされている
#             @sieve << i # ふるい落とされずに来たらそいつは素数
    
#             sieve_target = i * i
#             while sieve_target <= n do
#             @min_div[sieve_target] ||= i
#             sieve_target += i
#             end
#         end
#         (Math.sqrt(n).floor.next..n).each do |i|
#             next if @min_div[i]
#             @sieve << i
#         end
#     end
#     # Integer#prime_division と同じ値を返すようにする
#     # https://docs.ruby-lang.org/ja/latest/method/Integer/i/prime_division.html
#     def prime_division(num)
#         return num if !@min_div[num] # 素数のときすぐ返す
#         return_num = 1 # [[a, x], [b, y]] <=> num = a^x * b^y
#         while num > 1 do
#             prime = @min_div[num] # 最小の素因数, nil => numが素数
#             break return_num *= num if !prime
#             div_total = 0
#             while num % prime == 0 do
#             num /= prime
#             div_total += 1
#             end
#             return_num *= prime  if div_total % 2 != 0
#         end
#         return_num
#     end
#     def prime_list
#         @sieve
#     end
# end
# HeapQueue = PriorityQueue
# main

Submission Info

Submission Time
Task D - String Bags
User yoto1980yen
Language Ruby (ruby 3.2.2)
Score 425
Code Size 14326 Byte
Status AC
Exec Time 94 ms
Memory 18308 KiB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 425 / 425
Status
AC × 3
AC × 58
Set Name Test Cases
Sample sample_01.txt, sample_02.txt, sample_03.txt
All sample_01.txt, sample_02.txt, sample_03.txt, test_01.txt, test_02.txt, test_03.txt, test_04.txt, test_05.txt, test_06.txt, test_07.txt, test_08.txt, test_09.txt, test_10.txt, test_11.txt, test_12.txt, test_13.txt, test_14.txt, test_15.txt, test_16.txt, test_17.txt, test_18.txt, test_19.txt, test_20.txt, test_21.txt, test_22.txt, test_23.txt, test_24.txt, test_25.txt, test_26.txt, test_27.txt, test_28.txt, test_29.txt, test_30.txt, test_31.txt, test_32.txt, test_33.txt, test_34.txt, test_35.txt, test_36.txt, test_37.txt, test_38.txt, test_39.txt, test_40.txt, test_41.txt, test_42.txt, test_43.txt, test_44.txt, test_45.txt, test_46.txt, test_47.txt, test_48.txt, test_49.txt, test_50.txt, test_51.txt, test_52.txt, test_53.txt, test_54.txt, test_55.txt
Case Name Status Exec Time Memory
sample_01.txt AC 94 ms 17128 KiB
sample_02.txt AC 49 ms 17056 KiB
sample_03.txt AC 47 ms 17376 KiB
test_01.txt AC 46 ms 17180 KiB
test_02.txt AC 46 ms 17100 KiB
test_03.txt AC 49 ms 17600 KiB
test_04.txt AC 51 ms 17500 KiB
test_05.txt AC 51 ms 17608 KiB
test_06.txt AC 48 ms 17452 KiB
test_07.txt AC 49 ms 17500 KiB
test_08.txt AC 50 ms 17612 KiB
test_09.txt AC 51 ms 17544 KiB
test_10.txt AC 49 ms 17540 KiB
test_11.txt AC 50 ms 17420 KiB
test_12.txt AC 48 ms 17532 KiB
test_13.txt AC 51 ms 17236 KiB
test_14.txt AC 75 ms 17980 KiB
test_15.txt AC 48 ms 17388 KiB
test_16.txt AC 52 ms 17616 KiB
test_17.txt AC 50 ms 17612 KiB
test_18.txt AC 48 ms 17456 KiB
test_19.txt AC 47 ms 17516 KiB
test_20.txt AC 49 ms 17432 KiB
test_21.txt AC 50 ms 17632 KiB
test_22.txt AC 52 ms 17600 KiB
test_23.txt AC 49 ms 17632 KiB
test_24.txt AC 50 ms 17584 KiB
test_25.txt AC 61 ms 18084 KiB
test_26.txt AC 51 ms 17620 KiB
test_27.txt AC 63 ms 18308 KiB
test_28.txt AC 49 ms 17492 KiB
test_29.txt AC 51 ms 17600 KiB
test_30.txt AC 48 ms 17524 KiB
test_31.txt AC 49 ms 17780 KiB
test_32.txt AC 52 ms 17572 KiB
test_33.txt AC 55 ms 17636 KiB
test_34.txt AC 50 ms 17420 KiB
test_35.txt AC 57 ms 18116 KiB
test_36.txt AC 51 ms 17504 KiB
test_37.txt AC 51 ms 17460 KiB
test_38.txt AC 51 ms 17492 KiB
test_39.txt AC 53 ms 17616 KiB
test_40.txt AC 52 ms 17544 KiB
test_41.txt AC 58 ms 17540 KiB
test_42.txt AC 52 ms 17724 KiB
test_43.txt AC 55 ms 17800 KiB
test_44.txt AC 50 ms 17460 KiB
test_45.txt AC 51 ms 17544 KiB
test_46.txt AC 49 ms 17416 KiB
test_47.txt AC 53 ms 17668 KiB
test_48.txt AC 55 ms 17728 KiB
test_49.txt AC 52 ms 17556 KiB
test_50.txt AC 56 ms 17508 KiB
test_51.txt AC 57 ms 18052 KiB
test_52.txt AC 51 ms 17564 KiB
test_53.txt AC 61 ms 18216 KiB
test_54.txt AC 52 ms 17520 KiB
test_55.txt AC 61 ms 18204 KiB