题意:
老师点名,顺序是1 -- n -- 1 排为一个循环,每列为1 -- m的顺序, 问点到最多次数和最少次数的人的次数以及(x,y)被点的次数。
分析:
由于点名有循环,故可先判断出每一个循环每个人被点名的次数,再乘以循环数,为答案一部分。
最后一个循环结束后k还有余数,从(1,1)暴力模拟,因为n*m才10000, 再加上前面的,就能得出答案。
注意 n=1 需要特判。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 int mp[105][105]; 5 int n, m, x, y; 6 LL c, k; 7 LL res1, res2, res3; 8 int main() 9 { 10 scanf("%d%d%I64d%d%d", &n, &m, &k, &x, &y); 11 if (n == 1) 12 { 13 LL a = k/m; 14 k %= m; 15 if (k == 0) res1 = res2 = res3 = a; 16 else 17 { 18 res1 = a+1; 19 res2 = a; 20 res3 = a; 21 if (y <= k) res3++; 22 } 23 } 24 else 25 { 26 memset(mp, 0, sizeof(mp)); 27 c = k / ((2*n-2) * m); 28 k %= (2*n-2)*m; 29 int r = 1; 30 while (k > 0) 31 { 32 if (r == 1) 33 { 34 for (r; r < n && k; r++) 35 { 36 for (int j = 1; j <= m && k; j++) 37 { 38 ++mp[r][j]; 39 k--; 40 } 41 } 42 } 43 else if (r == n) 44 { 45 for (r; r > 1 && k; r--) 46 { 47 for (int j = 1; j <= m && k; j++) 48 { 49 ++mp[r][j]; 50 k--; 51 } 52 } 53 } 54 } 55 res1 = 0, res2 = mp[1][1] + c; 56 for (int i = 1; i <= n; i++) 57 for (int j = 1; j <= m; j++) 58 { 59 if (i == 1 || i == n) 60 res1 = max(res1, mp[i][j] + c), res2 = min(res2, mp[i][j] + c); 61 else 62 res1 = max(res1, mp[i][j] + 2*c), res2 = min(res2, mp[i][j] + 2*c); 63 } 64 if (x == 1 || x == n) 65 res3 = c + mp[x][y]; 66 else 67 res3 = 2*c + mp[x][y]; 68 } 69 printf("%I64d %I64d %I64d\n", res1, res2, res3); 70 }
时间: 2024-11-07 12:26:13