思路:首先我认为只要能发生反应,就一定可以一直反应下去并超过k。快读读入k时如果位数大于18直接当做正无穷。然后判断是否是154和147的因数,记录下来,当可以凑成对时即可以,另外也特判了存在154和147的倍数或零次反应的情况。
个人感觉思路很正确,但是一直错,甚至越特判越低分……
希望能指出我的思路的错误,或者分享一下相似的思路。
代码:
#include<cstdio>
using namespace std;
long long T, n, k, sum, flag[100];
long long p[] = {2, 3, 7, 7, 11, 14, 21, 22, 49, 77};
long long rp[] = {77, 49, 22, 21, 14, 11, 7, 7, 3, 2};
inline long long read() {
long long x=0, digit=0;
char ch = getchar();
while(ch<'0' || ch>'9') ch = getchar();
while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+(ch^48), ++digit, ch=getchar();
return digit>=18 ? 1e18 : x;
}
int main() {
T = read();
while(T--) {
n=read(), k=read(), sum=flag[0]=0;
for(register long long i=1, a; i<=n; ++i) {
a=read(), sum+=a;
if(flag[0]) continue;
if((a%154==0 || a%147==0) && n>1) {
flag[0] = 1;
continue;
}
for(register int j=0; j<9; ++j) {
if(a%p[j] == 0) {
if(flag[rp[j]]!=0 && flag[rp[j]]!=i) flag[0] = 1;
else if(flag[p[j]] == 0) flag[p[j]] = i;
}
}
}
if(flag[0] || sum>=k) puts("Yes");
else puts("No");
for(register int i=0; i<=99; ++i) flag[i] = 0;
}
return 0;
}