题目大意:
一个班有n行m列座位,老师要点k个学生,老师点名的顺序是从第1行。。。。第n-1行,第n行,第n-1行。。。。。第2行,这样重复,同一行中一定是从左到右的顺序点名,问最后被点到次数最多的人被点了几次,被点到次数最少的人被点了几次,还有坐在x行y列的人被点了几次。
题目解法:
本质上就是找规律题,除了n=1和n=2的情况要分开考虑,剩下的都可以一起考虑。然后就是边界的判断了。
代码:
#include "iostream"
#include "cstdio"
#include "math.h"
#include "algorithm"
#include "string"
#include "string.h"
#include "vector"
#include "map"
#include "queue"
using namespace std;
long long n, m, k, x, y;
int main() {
while (scanf("%lld%lld%lld%lld%lld", &n, &m, &k, &x, &y) != EOF)
{
if (n == 1)
{
long long num = k / (n*m);
k -= num*n*m;
long long ans1 = num, ans2 = num, ans3 = num;
if (k != 0)
ans1++;
if (y <= k)
ans3++;
printf("%lld %lld %lld\n", ans1, ans2, ans3);
}
else if (n == 2)
{
long long num = k / (n*m);
k -= num*n*m;
long long ans1 = num, ans2 = num, ans3 = num;
if (k)
ans1++;
if ((x - 1)*m + y <= k)
ans3++;
printf("%lld %lld %lld\n", ans1, ans2, ans3);
}
else
{
long long num = k / (n*m + (n - 2)*m);
long long mxnum = num << 1;
long long mnnum = num;
k -= num*(n*m + (n - 2)*m);
long long ans1 = mnnum, ans2 = mxnum, ans3 = mxnum;
if (k)
ans1++;
if (k>m)
ans2++;
if (k>n*m)
ans2++;
ans1 = max(ans2, ans1);
ans2 = mnnum;
if (k >= n*m)
ans2++;
if (x == 1 || x == n)
ans3 = mnnum;
if ((x - 1)*m + y <= k)
ans3++;
if (n*m<k)
{
if (x != 1 && x != n)
{
if (n*m + (n - x - 1)*m + y <= k)
ans3++;
}
}
printf("%lld %lld %lld\n", ans1, ans2, ans3);
}
}
return 0;
}