注意,并不是区间上存在超过2个素数就不成立
当n > s 时 , 该条件不成立
比如数据 125 1 2361 2
事实上, 当n > s 时, 我们将s + 1 到 n 不动 , 此时只要判断 从n + 1 到 s + n 是否能成立
即转换为输入系数为 s n 是否成立
s = 0 是特判成立会快一些
其余即二分图可解决
#include <bits/stdc++.h>
using namespace std ;
typedef long long ll ;
bool check_prime(int x){
for(int i = 2 ; i <= sqrt(x) ; i ++ ){
if(x % i == 0) return false ;
}
return true ;
}
struct Edge
{
int from;
int to;
int weight;
Edge(int f, int t, int w):from(f), to(t), weight(w) {}
};
const int __maxNodes = 100000 ;
vector<int> G[__maxNodes];
vector<Edge> edges;
typedef vector<int>::iterator iterator_t;
int num_nodes;
int num_left;
int num_right;
int num_edges;
void add_edge_value_1(int l , int r){///attention add value is only 1
Edge a = Edge(l , r , 1) ;
edges.push_back(a);
G[l].push_back(edges.size() - 1) ;
a = Edge(r , l , 1) ;
edges.push_back(a) ;
G[r].push_back(edges.size() - 1) ;
}
int matching[__maxNodes];
int check[__maxNodes];
bool dfs(int u)
{
for (iterator_t i = G[u].begin(); i != G[u].end(); ++i) {
int v = edges[*i].to;
if (!check[v]) {
check[v] = true;
if (matching[v] == -1 || dfs(matching[v])) {
matching[v] = u;
matching[u] = v;
return true;
}
}
}
return false;
}
int hungarian()
{
int ans = 0;
memset(matching, -1, sizeof(matching));
for (int u=1; u <= num_left; ++u) {
if (matching[u] == -1) {
memset(check, 0, sizeof(check));
if (dfs(u))
++ans;
}
}
return ans;
}
/*
3
1000000000 1000000000
125 1
2361 2
*/
int main(){
int T ; scanf("%d" , &T) ;
int n , k ;
int kk = 1 ;
while(T --){
scanf("%d %d" , &n , &k) ;
printf("Case #%d: " ,kk++ ) ;
if(0 == k) { puts("Yes"); continue ; }
int num = 0 ;
if(n > k) swap(n , k) ;
///without up code , want pass the "125 1 " data
///but actually , 2 to 126 can treat like this , 2 to 125 don t move , 126 puts on 1
///just like if k < n , we can put k + 1 to n don t move , and question become weather n + 1 to k + n can put on the right place
///just become the (k , n)
for(int i = 1 + k ; i <= n + k ; i ++ ){
if(check_prime(i)) num ++ ;// cout << i << endl;
if(num >= 2) break ;
}
//cout << num << endl ;
if(num > 1) {puts("No") ; continue ; }
for(int i = 0 ; i <= 1000 ; i ++ )
G[i].clear();
edges.clear();
num_left = num_right = n ;
for(int i = 1 + k ; i <= n + k ; i ++ ){
for(int j = 1 ; j <= sqrt(i) && j <= n ; j ++ ){
if(i % j == 0){
add_edge_value_1(i - k + n , j ) ;
//cout << i << " " << i - k + n << " " << j << endl ;
if(i / j != j && i / j <= n ){
add_edge_value_1(i - k + n , i / j ) ;
}
}
}
}
int ans = hungarian() ;
//cout << ans << endl ;
if(ans == num_left) puts("Yes") ;
else puts("No") ;
}
return 0 ;
}