题目大意
一个 N × M N \times M N×M 长方形画对角线,求线划分出的两半面积相等的小格子的个数。
解题思路
先举简单的例子,如果是 1 × 3 1\times 3 1×3,可以看到,对角线的中点一定会过最中间的格子的中点:
而如果是 1 × 2 1 \times 2 1×2(有一个偶数),对角线的中点只会在最中间的边上:
所以答案可以分为求有几个这样的组,如现在求
2
×
6
2\times6
2×6,可以看作是两个
1
×
3
1\times3
1×3:
可以看到是有
2
2
2 个。那么这
2
2
2 个是怎么得出来的呢?求
2
2
2 和
6
6
6 的公因数即可~
所以就是求 gcd ( N , M ) \gcd(N,M) gcd(N,M),记作 g g g。若 N / g N / g N/g 和 M / g M / g M/g 有一个为偶数,答案为 0 0 0,否则为 g g g。
参考代码
#include<stdio.h>
#include<iostream>
#include<vector>
#include<cstring>
#include<cstdio>
#include<climits>
#include<cmath>
#include<algorithm>
#include<queue>
#include<deque>
#include<map>
#include<unordered_map>
#include<set>
#include<stack>
//#define LOCAL //提交时一定注释
#define VI vector<int>
#define eps 1e-8
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
using namespace std;
typedef long long LL;
typedef double db;
const int inf = 0x3f3f3f3f;
const LL INF = 1e18;
const int N = 1e5 + 10;
#define ls rt << 1
#define rs rt << 1 | 1
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
inline int readint() {int x; scanf("%d", &x); return x;}
int ans[N];
LL gcd(LL a, LL b) {
return b == 0 ? a : gcd(b, a % b);
}
int main() {
#ifdef LOCAL
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
LL m, n; cin >> m >> n;
LL g = gcd(n, m);
LL mg = m / g, ng = n / g;
if (!(mg & 1) || !(ng & 1)) cout << 0;
else {
cout << gcd(n, m);
}
return 0;
}