結果
| 問題 | No.1557 Binary Variable |
| コンテスト | |
| ユーザー |
ID 21712
|
| 提出日時 | 2026-05-21 18:57:14 |
| 言語 | Go (1.26.1) |
| 結果 |
AC
|
| 実行時間 | 950 ms / 2,000 ms |
| コード長 | 2,604 bytes |
| 記録 | |
| コンパイル時間 | 12,096 ms |
| コンパイル使用メモリ | 286,824 KB |
| 実行使用メモリ | 24,096 KB |
| 最終ジャッジ日時 | 2026-05-21 18:58:04 |
| 合計ジャッジ時間 | 48,021 ms |
|
ジャッジサーバーID (参考情報) |
judge3_1 / judge1_0 |
| 純コード判定待ち |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 34 |
ソースコード
package main
import . "fmt"
import . "os"
import bf "bufio"
import . "sort"
type T struct {
v,index,side int
}
func main() {
rd:=bf.NewReader(Stdin)
var n,m int
Fscan(rd,&n,&m)
ls := make([]int, m)
rs := make([]int, m)
for i := range ls {
Fscan(rd,&ls[i], &rs[i])
}
ans := solve(n, m, ls, rs)
Println(ans)
}
func solve(n,m int, ls, rs []int) int {
ts := make([]*T, 0, m*2)
for i := 0; i < m; i++ {
L := &T{ ls[i], i, 0 }
R := &T{ rs[i], i, 1 }
ts = append(ts, L, R)
}
Slice(ts, func(i, j int) bool {
d := ts[i].v - ts[j].v
if d == 0 {
return ts[i].side < ts[j].side
} else {
return d < 0
}
})
removed := make([]bool, m)
current := []*T{}
zeros := 0
for len(ts) > 0 {
t := ts[0]
ts = ts[1:]
if t.side == 0 {
current = append(current, t)
} else if !removed[t.index] {
zeros++
for _, c := range current {
removed[c.index] = true
}
current = current[:0]
}
}
return n-zeros
}
func init() {
check()
}
func check() {
const n = 10
const m = 5
ls := make([]int, m)
rs := make([]int, m)
used := make([]bool, n+1)
cnt := 0
var tes func(i int)
tes = func(i int) {
if i == m {
cnt++
ans := solve(n, m, ls, rs)
expect := bruteforce(n, m, ls, rs)
if ans != expect {
println("n=",n)
println("m=",m)
println(Sprintf("ls=%#v", ls))
println(Sprintf("rs=%#v", rs))
println("ans=",ans)
println("expect=",expect)
panic("bug")
}
return
}
for x := 1; x <= n; x++ {
if used[x] {
continue
}
for y := x; y <= n; y++ {
if used[y] {
continue
}
ls[i] = x
rs[i] = y
used[x] = true
used[y] = true
tes(i+1)
used[x] = false
used[y] = false
}
break
}
}
tes(0)
println("cnt=",cnt)
}
func bruteforce(n,m int, ls,rs []int) int {
ans := 0
for i := 0; i < (1 << n); i++ {
zerosum := make([]int, n+1)
for k,v := 0,i; k < n; k++ {
if (v&1) != 0 {
zerosum[k+1] = 1
}
v >>= 1
}
for k := 0; k < n; k++ {
zerosum[k+1] += zerosum[k]
}
ok := true
for j := 0; j < m; j++ {
cnt := zerosum[rs[j]]-zerosum[ls[j]-1]
if cnt == 0 {
ok = false
break
}
}
if !ok {
continue
}
ans = max(ans, n-zerosum[n])
}
return ans
}
/*
考察
LからRまでに0となるBが1つ以上あるようにする必要がある
Lの小さい組から拾っていき拾ったうちのどれかのRが来たらそこを0にして拾ったやつを全部破棄、という貪欲法(?)で求まる?
LとRが同じ値のがあるときLを先に処理する必要がある(サンプルが優しい)
*/
ID 21712