题意:
给你一个数n,然后给你2,3,5,7这四个素数,令
m=2i∗3j∗5k∗7l
i,j,k,l分别从零开始取,问你能取出来的m里比n大的最小的那个数是多少
思路:
先dfs搜一遍,将所有范围内可能的取值都存到数组里,然后二分查找。
AC代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
int numb[100000 + 5];
int numb2[100000 + 5];
int ss[100000 + 5];
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int n,m;
memset(numb2,0,sizeof(numb2));
memset(ss,0,sizeof(ss));
scanf("%d%d", &n,&m);
int max_ = 0;
for(int i = 1; i <= n; i++){
scanf("%d", numb+i);
if(m == 0){
max_ = max(max_,numb[i]);
}
}
int u,v;
for(int i = 1;i <= m;i++){
scanf("%d%d", &u, &v);
numb2[u]++;
numb2[v]++;
}
int jidian = 0;
int p1,p2;
for(int i = 1; i <= n; i++){
if(numb2[i] % 2 == 1){
jidian++;
if(jidian > 2)break;
if(jidian == 1){
p1 = i;
}
if(jidian == 2){
p2 = i;
}
}
else{
int temp = numb2[i] /2 %2;
if(temp&1){
ss[i] = 1;
}
}
}
if(m == 0){
//puts("0");
//printf("%d\n",max_);
printf("Impossible\n");
continue;
}
int ans = 0;
if(jidian == 0){
for(int i = 1;i <= n;i++){
if(ss[i])
ans ^= numb[i];
}
const int temp = ans;
int ttt;
ans = 0;
for(int i = 1;i <= n;i++){
ttt = temp;
if(numb2[i] != 0){
ttt ^= numb[i];
if(ttt > ans){
ans = ttt;
}
}
}
printf("%d\n",ans);
}
if(jidian == 2){
ss[p1] ^= 1;
ss[p2] ^= 1;
for(int i = 1;i <= n;i++){
if(ss[i])
ans ^= numb[i];
}
printf("%d\n",ans);
}
else{
printf("Impossible\n");
}
}
return 0;
}