ACM入门题:幼儿园买玩具-Go语言

16 篇文章 0 订阅

问题描述: 蒜厂幼儿园有n 个小朋友,每个小朋友都有自己想玩的玩具。身为幼儿园园长的你决定给幼儿园买一批玩具,由于经费有限,你只能买m 个玩具。已知玩具商店一共卖k 种玩具,编号为1,2,3,…k,你让每个小朋友把想玩的玩具编号都写在了纸上。你希望满足尽可能多的小朋友的需求,请计算出最多能满足多少个小朋友的玩具需求。
输入格式 第一行,输入三个整数n,m,k(1≤n≤100,1≤m≤k≤15)中间用空格分开。

接下来n 行,第i+1(0≤i<n) 行的第一个数字 a i a_i ai 代表第 i 个小朋友想玩的玩具数量,接下来有 a i a_i ai 个数字,代表这 a i a_i ai 个玩具的编号。

输出格式 输出一个整数,表示最多能满足多少小朋友的玩具需求。

样例输入

5 3 5
2 1 4
0
2 3 1
3 2 3 4
2 4 5

样例输出

3

思路

  • 二进制枚举所有状态
  • 记录每次状态购买玩具数和具体购买的情况(布尔数组实现)
  • 当状态的购买数等于实际购买数时展开检查
  • 检查满足了多少孩子的需求进而找出最值
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func maxChild(child_toy [][]int, m int, k int) int {
	res := 0
	toy_buy := make([]bool, k+1)	// 某状态下已买玩具情况用布尔数组表示
	toy_num := 0					// 某状态下已买玩具数目
	for i := 0; i < 1<<k; i++ {
		toy_buy = make([]bool, k+1)
		toy_num = 0
		for j := 0; j < k; j++ {
			if i&(1<<j) > 0 {
				toy_buy[j+1] = true
				toy_num++
			}
		}
		// 如果当前状态假设购买玩具数与实际购买玩具数相符合则展开检查
		if toy_num == m {
			child_num := 0
			for row := 0; row < len(child_toy); row++ {
				flag := true		// 标记是否满足孩子需求
				// 首数值代表该孩子玩具需求数
				for col := 1; col <= child_toy[row][0]; col++ {
					if !toy_buy[child_toy[row][col]] {	// 任意一个需求未满足则代表不符合需求
						flag = false
						break
					}
				}
				if flag {
					child_num++
				}
			}
			if res < child_num {	// 更新最大满足孩子数
				res = child_num
			}
		}
	}
	return res
}

func main() {
	var n, m, k int
	fmt.Scanf("%d %d %d\n", &n, &m, &k)
	child_toy := make([][]int, n)
	for i, _ := range child_toy {
		child_toy[i] = make([]int, k+1)
	}
	// 考虑到输入的稳定性采用bufio标准输入库
	sca := bufio.NewScanner(os.Stdin)
	for i := 0; i < n; i++ {
		if sca.Scan() {
			lineNums := strings.Split(sca.Text(), " ")
			for j := 0; j < len(lineNums); j++ {
				child_toy[i][j], _ = strconv.Atoi(lineNums[j])
			}
		}
	}
	// fmt.Println(child_toy)
	fmt.Println(maxChild(child_toy, m, k))
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值