【发布时间】:2016-09-20 00:16:51
【问题描述】:
我在四个小时前第一次问了这个问题。其实这个问题我搜索了6个多小时还是看不懂。
这个问题是关于通过给你 x[n] 和 y[n] 来给你 n 分。您应该找到这些点的两个子集,它们的凸包相交。您的回答应该是满足上述规则的案例数。
给定平面上的有限集合 S。对于每个有效的 i, 其中一个点具有坐标 (x[i], y[i])。积分都是 不同的,没有三个是共线的。
下面,CH(s) 表示集合 s 的凸包:即 包含集合 s 的所有凸多边形中的最小的。我们说 如果满足以下条件,则有序对 (s1, s2) 很有趣 满意:
1.s1 是 S 的子集
2.s2 是 S 的子集
3. 集合 s1 和 s2 是不相交的(即它们没有共同的元素)
4. 凸包 CH(s1) 和 CH(s2) 的交点具有正面积注意,S 中的某些点可能仍未使用(即, 它们既不在 s1 中,也不在 s2 中)。你被给予 所有点的坐标:s x 和 y。请计算并返回 有趣的集合对的数量,模 10^9 + 7。
例子
{1,0,-1,-1,0,1} {1,2,1,-1,-2,-1}
返回:14
我们有 14 个 解决方案:
s1 = {0,1,3},s2 = {2,4,5} s1 = {0,2,3},s2 = {1,4,5} s1 = {0,1,4},s2 = {2,3,5} s1 = {0,2,4},s2 = {1,3,5} s1 = {1,2,4},s2 = {0,3,5} s1 = {0,3,4},s2 = {1,2,5} s1 = {1,3,4},s2 = {0,2,5} s1 = {0,2,5},s2 = {1,3,4} s1 = {1,2,5},s2 = {0,3,4} s1 = {0,3,5},s2 = {1,2,4} s1 = {1,3,5},s2 = {0,2,4} s1 = {2,3,5},s2 = {0,1,4} s1 = {1,4,5},s2 = {0,2,3} s1 = {2,4,5},s2 = {0,1,3}
有很多我无法理解的解决方案,以下是其中之一。例如,ccw 是干什么用的?结果由两部分组成,为什么? 能否给我一些算法名称,一些关键字也可以,我可以在google上详细搜索一下?
这是解决此问题的一个示例代码:
#include <vector>
#include <iostream>
using namespace std;
const long long mod=1000000007ll;
struct IntersectingConvexHull{
public:
int count(vector<int> x, vector<int> y){
int n = x.size();
long long P2[110];
P2[0]=1ll;
for(int i=1;i<=n;i++){
P2[i]=P2[i-1]*2%mod;
}
long long C[110][110];
for(int i=0;i<=n;i++){
C[i][0]=C[i][i]=1ll;
for(int j=1;j<i;j++){
C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
}
}
long long X[100],Y[100];
for(int i=0;i<=n;i++){
X[i]=x[i];
Y[i]=y[i];
}
long long ans=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i==j)continue;
int c1=0,c2=0;
for(int k=0;k<n;k++){
if(k==i||k==j){
continue;
}
long long ccw=(X[i]-X[k])*(Y[j]-Y[k])-(Y[i]-Y[k])*(X[j]-X[k]);
if(ccw<0){
c1++;
}
else{
c2++;
}
}
if(c1>=2&&c2>=2){
ans+=((P2[c1]+mod-c1-1)%mod)*((P2[c2]+mod-c2-1)%mod)%mod;
ans%=mod;
}
}
}
long long A=0ll;
for(int i=3;i<=n;i++){
for(int j=3;j<=n-i;j++){
A+=C[n][i]*C[n-i][j]%mod;
A%=mod;
}
}
return (A+mod-ans)%mod;
}
};
【问题讨论】:
-
请不要张贴图片作为代码。而是发布代码。
-
但由于网站限制,我无法复制它们。
-
然后通过查看图像手动输入代码。
-
好的,等几分钟。
-
我又打了一遍