题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5090
题目大意是有n个数 给一个k
每次你只能给其中一个数加上“k的非负整数倍的值”(包括0)
问最终能否让这堆数变成从1到n各有一个
简单排序完贪心是不对的
正确的思想是同余类
因为实质上每次只能加k,所以模k同余的可归为一类
然后分别对每一个同余类是否有可能合法
不合法的情形有两种 a.该同余类内的数不够多或太多 b.该同余类内的对应位置的数不够小
如果按这种想法走还需特判一下模k得0的情况
总是可能是我写搓了 感觉本来挺简单的一个题怎么遍地是坑
#include <cstdio> #include <cstdlib> #include <ctime> #include <iostream> #include <cmath> #include <cstring> #include <algorithm> #include <stack> #include <set> #include <queue> #include <vector> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> P; const int maxn = 110; int T; int a[maxn]; int b[maxn]; int c[maxn][maxn]; int cnt[maxn]; int main() { //freopen("in.txt", "r", stdin); scanf("%d", &T); while(T--) { memset(cnt, 0, sizeof(cnt)); int n, k, m; scanf("%d%d", &n, &k); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); for(int i = 1; i <= n; i++) { b[i] = a[i] % k; if(b[i] == 0) b[i] += k; } for(int i = 1; i <= n; i++) { int loc = b[i]; c[loc][cnt[loc]++] = a[i]; } m = n % k; bool flag = true; for(int i = 1; i <= k && flag; i++) { if(i <= m) { if(cnt[i] != n/k + 1) flag = false; } else if(cnt[i] != n/k) flag = false; } for(int i = 1; i <= k && flag; i++) sort(c[i], c[i] + cnt[i]); for(int i = 1; i <= k && flag; i++) { int ub = i; for(int j = 0; j < cnt[i] && flag; j++) { if(c[i][j] > ub) flag = false; ub += k; } } if(flag) printf("Jerry\n"); else printf("Tom\n"); } return 0; }
时间: 2024-10-12 06:51:56