题意:老师点名顺序规则如下:第1排,第2排,……,第n-1排,第n排,第n-1排,……,第2排,第1排,第2排,……,第n-1排,第n排,……对于每排都是从左到右依次点名,问点名k个人后,所有人中最多的点名次数,最少的点名次数,以及位于x排y列处的同学的点名次数。
分析:
1、由于k很大,将第1排,第2排,……,第n-1排,第n排,第n-1排,……,第2排看成一个循环。
2、这个循环中有2*(n-1)*m个人,注意当n=1时,这个循环中有m个人,将这个循环人数记为tmp。
3、利用k/tmp,算出每个人在k/tmp次循环后的点名次数,再按点名规则将第k/tmp + 1次循环中应当被点到名的人涂色即可。
#include<bits/stdc++.h> #define Min(a, b) ((a < b) ? a : b) #define Max(a, b) ((a < b) ? b : a) typedef long long LL; typedef unsigned long long LLU; const int INT_INF = 0x3f3f3f3f; const int INT_M_INF = 0x7f7f7f7f; const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1}; const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1}; const int MOD = 1e9 + 7; const double pi = acos(-1.0); const double eps = 1e-8; const int MAXN = 100 + 10; const int MAXT = 500 + 10; using namespace std; LL ans[MAXN][MAXN]; int main(){ LL n, m, k, x, y; while(scanf("%I64d%I64d%I64d%I64d%I64d", &n, &m, &k, &x, &y) == 5){ memset(ans, 0, sizeof ans); LL tmp = (n == 1) ? m : 2 * (n - 1) * m; for(LL j = 1; j <= m; ++j){ for(LL i = 1; i <= n; ++i){ if(i == 1 || i == n) ans[i][j] = k / tmp; else ans[i][j] = k / tmp * 2; } } LL yu = k % tmp; for(LL i = 1; i <= n; ++i){ for(LL j = 1; j <= m; ++j){ if(yu){ ++ans[i][j]; --yu; } else break; } } for(LL i = n - 1; i > 1; --i){ for(LL j = 1; j <= m; ++j){ if(yu){ ++ans[i][j]; --yu; } else break; } } LL ma = 0; LL mi = 1e18; for(LL i = 1; i <= n; ++i){ for(LL j = 1; j <= m; ++j){ ma = Max(ma, ans[i][j]); mi = Min(mi, ans[i][j]); } } printf("%I64d %I64d %I64d\n", ma, mi, ans[x][y]); } return 0; }