题目描述:
给你一个队列,队列长度是L,你可以对这个队列循环进行读操作和写操作,写操作(写入W个字符)时,如果队列中空余长度大于写的长度,那么可写,否则需要先进行读操作(读R个字符),等写空间大于W时,才能进行写操作;
不可读:队列中的可读字符不超过R个,则不可读
不可写:队列中的可写长度不超过W个,则不可写
在这个读写过程中,可能出现死锁现象:例如,在写操作时空余长度小于W即不可写,但是此时可读长度小于R即不可读,这就出现了死锁,两个操作都在等待对方;
测试用例是这样的:
输入参数:
5 2 3
输出:
OK;
输入参数:
5 3 4
输出:
DEAMLOCK//死锁
输入参数L,R,W;分别代表:队列长度,读操作长度,写操作长度;
解决思路:
状态判断:记录两个状态:队列可读长度和队列可写长度;如果不存在死锁,那么这两个状态必然会重复出现;存在死锁:就是不可读也不可写的时候
然后详细说明一下为什么不存在死锁是,是会有状态重复的:以5,2,3为例
队列可读长度 队列可写长度 执行操作
0 5 写
3 2 读
1 4 写
4 1 读
2 3 读
0 5
状态又重复了,这样循环下去是不会存在死锁了
这道题的关键在于什么时候判断不是死锁,死锁的判断条件比较简单,就是不可读加不可写
好了下面要贴代码了:说明一下,我是用map结构来存状态的
import java.util.*;
public class Main {
static HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int L = sc.nextInt();
int R = sc.nextInt();
int W = sc.nextInt();
find(0,L,R,W);
}
public static void find(int empty, int ocupy,int R,int W){
//是否可以先读
if(R <= ocupy){
if (solution(empty+R, ocupy-R,R,W)) {
System.out.println("OK");
return;
}
}
//是否可以先写
if(W <= empty){
if (solution(empty-W, ocupy,R,W)) {
System.out.println("OK");
return;
}
}
System.out.println("DEADLOCK");
}
public static boolean solution(int empty, int ocupy,int R,int W){
if(map.containsKey(empty)){
if(map.get(empty) == ocupy){
return true;
}
}
map.put(empty+R, ocupy-R);
//是否可以先读
if(R <= ocupy){
if (solution(empty+R, ocupy-R,R,W)) return true;
}
//是否可以先写
if(W <= empty){
if (solution(empty-W, ocupy,R,W)) return true;
}
return false;
}
}