标签:
题目大意:一个平面内有一些无限长的直线,把平面分成了若干块,从一块走一步可以走到与它有公共边的另一块,但是只有公共点不能一步走过去。给定两个在块内部的点,问从S点到T点最少走几步。
题目分析:由于每步只能跨越公共边,不能从两直线交点处跨越,所以一步只能越过 S 与 T 之间的一条直线,那么答案就是 S 与 T 之间有多少条直线(即 S 与 T 在这些直线的两侧)。判断 S 与 T 在直线 l 两侧 : l : ax + by + c = 0 (a*Sx + b*Sy + c) 与 (a*Tx + b*Ty + c) 异号。
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int MaxN = 300 + 5; int Sx, Sy, Tx, Ty, n, Ans, a, b, c; typedef long long LL; LL N1, N2; int main() { scanf("%d%d%d%d", &Sx, &Sy, &Tx, &Ty); scanf("%d", &n); Ans = 0; for (int i = 1; i <= n; ++i) { scanf("%d%d%d", &a, &b, &c); N1 = (LL)a * (LL)Sx + (LL)b * (LL)Sy + (LL)c; N2 = (LL)a * (LL)Tx + (LL)b * (LL)Ty + (LL)c; if (N1 > 0) N1 = 1; else N1 = -1; if (N2 > 0) N2 = 1; else N2 = -1; if (N1 * N2 < 0) ++Ans; } printf("%d\n", Ans); return 0; }
题目大意:
给定一个序列 A[n] ,还有一些实数对 (i, j) ,满足 i + j 为奇数。每次可以进行一次操作:选取一个实数对 (i, j),如果 A[i] 和 A[j] 不互质,就可以 ++Ans,然后将他们同除以一个大于 1 的公因子。这些实数对可重复利用。问 Ans 最多可以多大。
题目分析:
题目中的实数对为 (i, j) 满足 i + j 为奇数,所以 i 与 j 一个是奇数,一个是偶数。那么所有的实数对就相当于在每对 i,j 之间的连边,这样就组成一个二分图,只有下标为偶数的数和下标为奇数的数可能连边,奇数与奇数,偶数与偶数不能连边。
这个题的操作描述中的网络流气息十分明显...那么就是求最大流,下面我们来建图:
对于每个下标为奇数的数,将它分解质因数,从每个(质因数点1)向它连容量为这个质因数的指数的边。
对于每个下标为偶数的数,将它分解质因数,从它向每个(质因数点2)连容量为这个质因数的指数的边。
对于每个(质因数点1),我们从 S 向它连 INF 边;对于每个(质因数点2),我们从它向 T 连 INF 边。
对于每个实数对,我们从奇数向偶数连 INF 边。
这样求最大流就可以了。
代码:
Codeforces Round #284 (Div. 2)
标签:
原文地址:http://www.cnblogs.com/JoeFan/p/4185204.html