长安大学第四届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;
}

浙公网安备 33010602011771号