結果

問題 No.15 カタログショッピング
ユーザー warashiwarashi
提出日時 2016-05-26 19:16:59
言語 Go
(1.22.1)
結果
AC  
実行時間 32 ms / 5,000 ms
コード長 2,409 bytes
コンパイル時間 11,109 ms
コンパイル使用メモリ 223,332 KB
実行使用メモリ 5,376 KB
最終ジャッジ日時 2024-04-19 08:00:49
合計ジャッジ時間 11,348 ms
ジャッジサーバーID
(参考情報)
judge4 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
5,248 KB
testcase_01 AC 2 ms
5,376 KB
testcase_02 AC 1 ms
5,376 KB
testcase_03 AC 2 ms
5,376 KB
testcase_04 AC 1 ms
5,376 KB
testcase_05 AC 28 ms
5,376 KB
testcase_06 AC 32 ms
5,376 KB
testcase_07 AC 30 ms
5,376 KB
testcase_08 AC 30 ms
5,376 KB
testcase_09 AC 31 ms
5,376 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

package main

import (
	"fmt"
	"sort"
	"strconv"
	"strings"
)

type priceAndItem struct {
	p int
	i int32
}
type priceAndItemS []priceAndItem

func (p priceAndItemS) Len() int {
	return len(p)
}
func (p priceAndItemS) Swap(i, j int) {
	p[i], p[j] = p[j], p[i]
}
func (p priceAndItemS) Less(i, j int) bool {
	return p[i].p < p[j].p
}

type items [][]int

func (is items) Len() int {
	return len(is)
}
func (is items) Swap(i, j int) {
	is[i], is[j] = is[j], is[i]
}
func (is items) Less(i, j int) bool {
	a := is[i]
	b := is[j]
	for k := 0; ; k++ {
		if len(a) <= k {
			return true
		}
		if len(b) <= k {
			return false
		}
		if a[k] == b[k] {
			continue
		}
		return a[k] < b[k]
	}
}

func bit2list(b int32) []int {
	l := make([]int, 0, 32)
	for i := uint(0); i < 32; i++ {
		if (b & (1 << i)) == 0 {
			continue
		}
		l = append(l, int(i+1))
	}
	return l
}
func conv(l []int) string {
	s := make([]string, 0, 32)
	for _, i := range l {
		s = append(s, strconv.Itoa(i))
	}
	return strings.Join(s, " ")
}

func price(P []int, l int32) int {
	p := 0
	for i := uint(0); i < uint(len(P)); i++ {
		if (l & (1 << i)) == 0 {
			continue
		}
		p += P[i]
	}
	return p
}
func search(S int, fh, lh priceAndItemS) []int32 {
	var res []int32
	for i := range fh {
		j := sort.Search(len(lh), func(j int) bool { return fh[i].p+lh[j].p >= S })

		if len(lh) <= j {
			continue
		}
		if fh[i].p+lh[j].p == S {
			var k int
			for {
				if len(lh) <= j+k || lh[j].p != lh[j+k].p {
					break
				}
				res = append(res, fh[i].i|lh[j+k].i)
				k++
			}
		}
	}
	return res
}

func main() {
	var N, S int
	fmt.Scan(&N, &S)
	P := make([]int, N)
	for i := range P {
		fmt.Scan(&P[i])
	}
	fh := make(priceAndItemS, 0, 1<<uint(N/2))
	for i := int32(0); i < 1<<uint(N/2); i++ {
		fh = append(fh, priceAndItem{
			p: price(P, i),
			i: i,
		})
	}
	var tmp uint
	if N%2 == 0 {
		tmp = uint(N / 2)
	} else {
		tmp = uint(N/2 + 1)
	}

	lh := make(priceAndItemS, 0, 1<<tmp)
	for i := int32(0); i < 1<<tmp; i++ {
		item := i << uint(N/2)
		lh = append(lh, priceAndItem{
			p: price(P, item),
			i: item,
		})
	}
	sort.Sort(fh)
	sort.Sort(lh)

	res := search(S, fh, lh)

	resL := make([][]int, 0, len(res))
	for _, l := range res {
		resL = append(resL, bit2list(l))
	}
	sort.Sort(items(resL))

	resS := make([]string, 0, len(res))
	for _, i := range resL {
		resS = append(resS, conv(i))
	}
	for _, s := range resS {
		fmt.Println(s)
	}
}
0