前言
拼多多的一场机试 解题报告
有需要机试辅导,可以私信我
机试题
D. 任务队列是否会死锁?
一个任务队列,长度为n
- 可以添加一个任务,长度为a
- 可以获取一个任务,长度为b
如果存在一个状态点,即不能添加任务,也不能获取任务,即为死锁状态
0 < n , a , b < 1 e 18 0<n,a,b<1e18 0<n,a,b<1e18
因为这个数据范围很大,所以定然是数论题。
先找找死锁的点,假设存在一个点z
其满足 n − a < z < b n - a < z < b n−a<z<b
即不能添加,也不能获取,此时必然是死锁点。
但是光有这个还是不够的
也要进行可达点的分析
我们引入方程
z = a x − b y , z 为可取的非负整数 z = ax - by, z为可取的非负整数 z=ax−by,z为可取的非负整数
由裴蜀定律,这个z必然是 gcd(a, b)的倍数
那这题就很清楚了
即 z ∈ [ n − a + 1 , b − 1 ] , 如果存在 g c d ( a , b ) 的倍数点,则存在死锁风险点,反之无 z\in[n - a + 1, b - 1], 如果存在 gcd(a, b)的倍数点,则存在死锁风险点,反之无 z∈[n−a+1,b−1],如果存在gcd(a,b)的倍数点,则存在死锁风险点,反之无
由容斥定律
令
g
=
g
c
d
(
a
,
b
)
令g = gcd(a, b)
令g=gcd(a,b)
(
b
−
1
)
/
g
−
(
n
−
a
)
/
g
>
0
,
则存在死锁的风险
(b - 1) / g - (n - a) / g > 0, 则存在死锁的风险
(b−1)/g−(n−a)/g>0,则存在死锁的风险
import java.io.BufferedInputStream;
import java.util.Scanner;
public class Main {
static long gcd(long a, long b) {
return b == 0 ? a : gcd(b, a % b);
}
public static void main(String[] args) {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
int t = sc.nextInt();
while (t-- > 0) {
long n = sc.nextLong();
long a = sc.nextLong();
long b = sc.nextLong();
// 限制条件:n - a < x < b
// 裴蜀定理 ax - by = gcd(a, b)
long g = gcd(a, b);
// 容斥定理
long r = (b - 1) / g - (n - a) / g;
if (r > 0) {
System.out.println("Yes");
} else {
System.out.println("No");
}
}
}
}
附带测试数据:
- 输入
2
7 5 6
7 3 5
- 输出
Yes
No