Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions Algorithm/greedy algorithm/atcoder/A72/A72.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package main

import (
"bufio"
"fmt"
"os"
"sort"
)

func max(a, b int) int {
if a > b {
return a
}
return b
}

func main() {
sc := bufio.NewScanner(os.Stdin)
sc.Split(bufio.ScanLines)

sc.Scan()
var H, W, K int
fmt.Sscanf(sc.Text(), "%d %d %d", &H, &W, &K)

grid := make([][]rune, H)
for i := 0; i < H; i++ {
sc.Scan()
row := []rune(sc.Text())
grid[i] = row
}

maxBlack := 0

// 全ての行選択パターンをビット列で列挙
for bit := 0; bit < (1 << H); bit++ {
paintedRows := []int{}
for i := 0; i < H; i++ {
if (bit>>i)&1 == 1 {
paintedRows = append(paintedRows, i)
}
}

if len(paintedRows) > K {
continue
}

// gridのコピー(deep copy)
painted := make([][]rune, H)
for i := 0; i < H; i++ {
painted[i] = make([]rune, W)
copy(painted[i], grid[i])
}

// 選んだ行を黒く塗る
for _, row := range paintedRows {
for j := 0; j < W; j++ {
painted[row][j] = '#'
}
}

// 各列の黒マス数を数える
blackCount := make([]int, W)
for j := 0; j < W; j++ {
for i := 0; i < H; i++ {
if painted[i][j] == '#' {
blackCount[j]++
}
}
}

// gain を計算(白マスの多い列を貪欲に選ぶ)
type gainCol struct {
gain int
col int
}
gains := []gainCol{}
for j := 0; j < W; j++ {
gains = append(gains, gainCol{H - blackCount[j], j})
}
sort.Slice(gains, func(i, j int) bool {
return gains[i].gain > gains[j].gain
})

// 残りの K - 行数 だけ列を塗る
columnsToPaint := make(map[int]bool)
remain := K - len(paintedRows)
for i := 0; i < remain && i < len(gains); i++ {
columnsToPaint[gains[i].col] = true
}

// 黒マスの総数を数える
total := 0
for i := 0; i < H; i++ {
for j := 0; j < W; j++ {
if painted[i][j] == '#' || columnsToPaint[j] {
total++
}
}
}

maxBlack = max(maxBlack, total)
}

fmt.Println(maxBlack)
}
62 changes: 62 additions & 0 deletions Algorithm/greedy algorithm/atcoder/A72/A72.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
const fs = require('fs');

const input = fs.readFileSync('/dev/stdin', 'utf8').trim().split('\n');
const [H, W, K] = input[0].split(' ').map(Number);
const grid = input.slice(1).map(line => line.split(''));

let maxBlack = 0;

for (let bit = 0; bit < (1 << H); bit++) {
const paintedRows = [];
for (let i = 0; i < H; i++) {
if ((bit >> i) & 1) paintedRows.push(i);
}
const rowPaintCount = paintedRows.length;
if (rowPaintCount > K) continue;

const painted = Array.from({ length: H }, (_, i) =>
grid[i].slice()
);

// 行を黒く塗る
for (const row of paintedRows) {
for (let j = 0; j < W; j++) {
painted[row][j] = '#';
}
}

// 各列の黒マス数を数える
const blackCountPerCol = Array(W).fill(0);
for (let j = 0; j < W; j++) {
for (let i = 0; i < H; i++) {
if (painted[i][j] === '#') blackCountPerCol[j]++;
}
}

// 残りの操作回数で列を黒く塗る(貪欲に黒マスの増加が大きいものを選ぶ)
const columnGain = [];
for (let j = 0; j < W; j++) {
const gain = H - blackCountPerCol[j];
columnGain.push([gain, j]);
}
columnGain.sort((a, b) => b[0] - a[0]);

const columnsToPaint = new Set();
for (let i = 0; i < K - rowPaintCount && i < columnGain.length; i++) {
columnsToPaint.add(columnGain[i][1]);
}

// 合計黒マス数を数える
let totalBlack = 0;
for (let i = 0; i < H; i++) {
for (let j = 0; j < W; j++) {
if (painted[i][j] === '#' || columnsToPaint.has(j)) {
totalBlack++;
}
}
}

maxBlack = Math.max(maxBlack, totalBlack);
}

console.log(maxBlack);
74 changes: 74 additions & 0 deletions Algorithm/greedy algorithm/atcoder/A72/A72.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

list($H, $W, $K) = array_map('intval', explode(' ', trim(fgets(STDIN))));
$grid = [];
for ($i = 0; $i < $H; $i++) {
$grid[] = str_split(trim(fgets(STDIN)));
}

$maxBlack = 0;

for ($bit = 0; $bit < (1 << $H); $bit++) {
$paintedRows = [];
for ($i = 0; $i < $H; $i++) {
if (($bit >> $i) & 1) {
$paintedRows[] = $i;
}
}

$rowCount = count($paintedRows);
if ($rowCount > $K) continue;

// グリッドのコピー
$painted = [];
foreach ($grid as $row) {
$painted[] = $row;
}

// 行を黒く塗る
foreach ($paintedRows as $i) {
for ($j = 0; $j < $W; $j++) {
$painted[$i][$j] = '#';
}
}

// 各列の黒マス数をカウント
$blackCount = array_fill(0, $W, 0);
for ($j = 0; $j < $W; $j++) {
for ($i = 0; $i < $H; $i++) {
if ($painted[$i][$j] === '#') {
$blackCount[$j]++;
}
}
}

// 残りの操作回数で列を貪欲に塗る
$gain = [];
for ($j = 0; $j < $W; $j++) {
$gain[] = ['gain' => $H - $blackCount[$j], 'col' => $j];
}

usort($gain, function ($a, $b) {
return $b['gain'] <=> $a['gain'];
});

$columnsToPaint = [];
$remainingOps = $K - $rowCount;
for ($k = 0; $k < min($remainingOps, $W); $k++) {
$columnsToPaint[$gain[$k]['col']] = true;
}

// 黒マスを数える
$totalBlack = 0;
for ($i = 0; $i < $H; $i++) {
for ($j = 0; $j < $W; $j++) {
if ($painted[$i][$j] === '#' || isset($columnsToPaint[$j])) {
$totalBlack++;
}
}
}

$maxBlack = max($maxBlack, $totalBlack);
}

echo $maxBlack . "\n";
59 changes: 59 additions & 0 deletions Algorithm/greedy algorithm/atcoder/A72/A72.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import sys
from itertools import combinations

def main():
input = sys.stdin.read
data = input().strip().split('\n')

H, W, K = map(int, data[0].split())
grid = [list(row) for row in data[1:]]

max_black = 0

for bit in range(1 << H):
painted_rows = []
for i in range(H):
if (bit >> i) & 1:
painted_rows.append(i)

row_count = len(painted_rows)
if row_count > K:
continue # 操作回数オーバー

# 行を黒く塗ったグリッドを作る
painted = [row[:] for row in grid] # deepcopy
for i in painted_rows:
painted[i] = ['#'] * W

# 各列の黒マス数を数える
black_count_per_col = [0] * W
for j in range(W):
for i in range(H):
if painted[i][j] == '#':
black_count_per_col[j] += 1

# 残りの K-row_count 回で最も gain の大きい列を選ぶ
column_gain = []
for j in range(W):
gain = H - black_count_per_col[j] # 黒く塗れば gain だけ黒が増える
column_gain.append((gain, j))

column_gain.sort(reverse=True)
remaining_ops = K - row_count
columns_to_paint = set()
for i in range(min(remaining_ops, W)):
columns_to_paint.add(column_gain[i][1])

# 最終的な黒マス数を数える
total_black = 0
for i in range(H):
for j in range(W):
if painted[i][j] == '#' or j in columns_to_paint:
total_black += 1

max_black = max(max_black, total_black)

print(max_black)

if __name__ == "__main__":
main()
66 changes: 66 additions & 0 deletions Algorithm/greedy algorithm/atcoder/A72/A72.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import * as fs from 'fs';

const input = fs.readFileSync('/dev/stdin', 'utf8').trim().split('\n');
const [H, W, K] = input[0].split(' ').map(Number);
const grid: string[][] = input.slice(1).map(line => line.split(''));

let maxBlack = 0;

for (let bit = 0; bit < (1 << H); bit++) {
const paintedRows: number[] = [];
for (let i = 0; i < H; i++) {
if ((bit >> i) & 1) paintedRows.push(i);
}

const rowPaintCount = paintedRows.length;
if (rowPaintCount > K) continue;

// 塗り操作のコピー
const painted: string[][] = grid.map(row => [...row]);

// 行を黒に塗る
for (const row of paintedRows) {
for (let j = 0; j < W; j++) {
painted[row][j] = '#';
}
}

// 各列の黒マス数
const blackCountPerCol: number[] = new Array(W).fill(0);
for (let j = 0; j < W; j++) {
for (let i = 0; i < H; i++) {
if (painted[i][j] === '#') {
blackCountPerCol[j]++;
}
}
}

// 残り操作回数で列を貪欲に選ぶ
const columnGain: [number, number][] = [];
for (let j = 0; j < W; j++) {
const gain = H - blackCountPerCol[j];
columnGain.push([gain, j]);
}

columnGain.sort((a, b) => b[0] - a[0]);

const columnsToPaint = new Set<number>();
const remainingCols = K - rowPaintCount;
for (let i = 0; i < Math.min(remainingCols, columnGain.length); i++) {
columnsToPaint.add(columnGain[i][1]);
}

// 黒マス合計を計算
let totalBlack = 0;
for (let i = 0; i < H; i++) {
for (let j = 0; j < W; j++) {
if (painted[i][j] === '#' || columnsToPaint.has(j)) {
totalBlack++;
}
}
}

maxBlack = Math.max(maxBlack, totalBlack);
}

console.log(maxBlack);
Loading