长安大学第四届ACM-ICPC“迎新杯”程序设计竞赛-重现赛 D - 新卡片游戏
题目描述
𝑐𝑡𝑟与𝑑𝑓𝑑在玩一个游戏,𝑐𝑡𝑟有𝑛张卡片,每张卡片上写了一个数字,其中第𝑖张卡片上的数字为𝑎𝑖。𝑑𝑓𝑑说出了一个质数𝑝,并指出可以将𝑛张卡片重新排列使得相邻两张卡片上数字的乘积是𝑝2 的倍数,即重新排列后满足𝑎𝑖 × 𝑎𝑖+1 𝑚𝑜𝑑 𝑝2 = 0(𝑖 < 𝑛)。𝑐𝑡𝑟 对此表示怀疑,并与𝑑𝑓𝑑打赌,输的人会受到相应的惩罚。
𝑑𝑓𝑑欣然接受了他的挑战,他想知道自己能否赢得这次赌注。
𝑑𝑓𝑑欣然接受了他的挑战,他想知道自己能否赢得这次赌注。
输入描述:
输入第一行为一个整数𝑇(1 ≤ 𝑇 ≤ 20),表示一共有𝑇组测试数据。
对于每组测试数据:
第一行有两个整数𝑛(2 ≤ 𝑛 ≤ 104)和𝑝(1 ≤ 𝑝 ≤ 105),表示卡片总数与𝑑𝑓𝑑提到的的质数。
第二行有𝑛个整数,其中第𝑖个数字𝑎𝑖(1 ≤ 𝑎𝑖 ≤ 105)代表了第𝑖张卡片上的字母。
数据保证𝑝是一个质数。
输出描述:
对于每组测试数据,输出如果dfd能够赢得这次赌注输出“YES”,否则输出“NO”。
示例1
输入
2 5 2 4 4 1 1 1 5 3 3 3 2 2 2
输出
YES NO
说明
对于第一组样例,卡片重新排列成1 4 1 4 1便能够满足要求。
对于第二组样例,不论怎么排序都无法满足要求。
题解
分析。
先处理出每个数能被几个$p$除掉,然后只要考虑$0$的个数和大于等于$2$的个数就可以了。
因为只有大于等于$2$的东西才可以消掉$0$。
#include <bits/stdc++.h> using namespace std; const int maxn = 10000 + 10; int T, n, p; int main() { scanf("%d", &T); while(T --) { scanf("%d%d", &n, &p); int sum0 = 0, sum2 = 0; for(int i = 1; i <= n; i ++) { int x; scanf("%d", &x); int k = 0; while(x) { if(x % p) break; k ++; x = x / p; } if(k == 0) sum0 ++; if(k >= 2) sum2 ++; } if(sum2) { sum0 = sum0 - min(sum0, sum2 + 1); } if(sum0 == 0) printf("YES\n"); else printf("NO\n"); } return 0; }