题目链接:http://codeforces.com/problemset/problem/32/C
本文链接:http://www.cnblogs.com/Ash-ly/p/5513436.html
题意:
给你一个M*N的方格,有一个青蛙每次只能跳S步,问能够跳最多次数的起点有多少个.
思路:
首先,第一个格子肯定是可以作为起点的,那么往下能跳的点数为(M - 1) / S +1,往右能跳的点数为(N - 1) / S +1,这些点又都可以各自作为起点,所以假设以第一个格子为起点那么起点的个数应该为 ( (M - 1) / S +1 ) * ( (N - 1) / S +1 ),那么这些路径可以想象成构成了一个矩形,这个矩形可以往下平移,往下平移的个数为row = M - (M - 1) / S * S +1(注:其中(M - 1) / S * S +1为向下走的格子数),也可以往右平移,且个数为line = N - (N - 1) / S * S +1, 也可以往右下方平移,个数为line * row;再加上自己本身的1个,那么总个数为(row + line + row * line + 1),每个又有 ( (M - 1) / S +1 ) * ( (N - 1) / S +1 )个起点,所以总数为 ( (M - 1) / S +1 ) * ( (N - 1) / S +1 ) * (row + line + row * line + 1).当N和M都不大于S时,答案为N*M.
代码:
1 #include <iostream> 2 #include <cmath> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 #include <algorithm> 7 #include <string> 8 #include <queue> 9 #include <stack> 10 #include <vector> 11 #include <map> 12 using namespace std; 13 typedef long long LL; 14 int main() 15 { 16 //freopen("input.txt", "r", stdin); 17 LL m, n, s; 18 while(cin >> m >> n >> s){ 19 LL row = m - (1 + (m - 1) / s * s);//向下平移的种类数 20 LL line = n - (1 + (n - 1) / s * s );//向右平移的种类数 21 LL Rpoint = (n - 1) / s + 1 ; 22 LL Lpoint = (m - 1)/ s + 1;//Rpoint * Lpoint为以第一个格子为起点时起点的个数 23 if(s >= max(m, n)) {cout << n * m <<endl;continue;}//这种情况特判 24 cout << (row + line + (row * line) + 1) * (Rpoint * Lpoint) << endl; 25 } 26 return 0; 27 }