```golang
package main
import "fmt"
import "sync"
type Node struct {
h, w int
}
var (
arr = make([]Node, 1e5)
n, k int
ch = make(chan int)
judge = make(chan bool)
wg sync.WaitGroup
)
func check() {
tot, num := 0, <-ch
for i := 0; i < n; i++ {
tot += (arr[i].h / num) * (arr[i].w / num)
if tot >= k {
judge <- true
return
}
}
judge <- false
}
func main() {
fmt.Scanf("%d %d", &n, &k)
for i := 0; i < n; i++ {
fmt.Scanf("%d %d", &arr[i].h, &arr[i].w)
}
wg.Add(1)
go check()
go func() {
l, r := 1, 100000
for l < r {
mid := (l + r + 1) >> 1
ch <- mid
if <-judge {
l = mid
} else {
r = mid - 1
}
}
ch <- l
wg.Done()
}()
fmt.Println(<-ch)
wg.Wait()
}
```
输入:
```
2 10
5 6
6 5
```
输出:
```
2
```
首先输入有问题
简单看下死锁问题,ch写入mid,有可能直接被main中的fmt.Println(<-ch)读取,那么check函数锁死,if <-judge 锁死。
再看,if <-judge在for内,那么可能会读很多次,你check只执行一次即judge只写入一次。
另外,这个好像没有必要用通道吧,按顺序逻辑写就行
```
package main
import "fmt"
import "sync"
type Node struct {
h, w int
}
var (
arr = make([]Node, 1e5)
n, k int
ch = make(chan int)
judge = make(chan bool)
wg sync.WaitGroup
)
func check() {
tot, num := 0, <-ch
for i := 0; i < n; i++ {
tot += (arr[i].h / num) * (arr[i].w / num)
if tot >= k {
judge <- true
return
}
}
judge <- false
}
func main() {
fmt.Scanf("%d %d\n", &n, &k)
for i := 0; i < n; i++ {
fmt.Scanf("%d %d\n", &arr[i].h, &arr[i].w)
}
wg.Add(1)
go func() {
l, r := 1, 100000
for l < r {
go check()
mid := (l + r + 1) >> 1
ch <- mid
if <-judge {
l = mid
} else {
r = mid - 1
}
}
go func(){
ch <- l
}()
wg.Done()
}()
wg.Wait()
fmt.Println(<-ch)
}
```
#1
更多评论
应该是和judge通道没关系,是ch通道和wg的问题,主进程你用wg等待子进程执行完成,子进程又在等待主进程的ch读取,所以死锁了
去掉wg就行,改成这样试试
```
func main() {
fmt.Scanf("%d %d", &n, &k)
for i := 0; i < n; i++ {
fmt.Scanf("%d %d", &arr[i].h, &arr[i].w)
}
// wg.Add(1)
go check()
go func() {
l, r := 1, 100000
for l < r {
mid := (l + r + 1) >> 1
ch <- mid
if <-judge {
l = mid
} else {
r = mid - 1
}
}
ch <- l
// wg.Done()
}()
fmt.Println(<-ch)
// wg.Wait()
}
```
#2