/*
将六边形的顶点分为三类,即分别与一个、两个、三个六边形相邻。
过六边形的中心,做各边的垂线,可将六边形等分成六份。
其中每一份中,硬币落在其上的三种概率,仅与其顶点类型相关。
1、 首先求出每种顶点对应的三种概率的值。
2、 再算出每种顶点的个数。
3、 将顶点的个数作为权,求出加权概率即得解。
*/
#include<iostream>
#include<cstdio>
using namespace std;
#define MAX_N 1000
#define MAX_M 1000
#define SQRT3 1.7320508075688772935274463415059//根号3
#define AREA (3*SQRT3/2)//六边形面积
#define PI 3.1415926535897932384626433832795
int main() {
int N, M, K;
long double R;
long double area1_1, area2_1, area2_2, area3_1, area3_2, area3_3;//不同类型顶点对应不同落点的面积
long double area, area1, area2, area3;//总面积
int point1, point2, point3;//不同类型顶点的个数
int count;//六边形个数
int T = 1;
while (cin >> N >> M >> K) {
if (N == 0 && M == 0 && K == 0) break;
cin >> R;
//与一个六边形相邻的顶点
area1_1 = AREA / 6;//落在一个六边形上
//与两个六边形相邻的顶点
area2_2 = (R*PI / 6 + 1)*R / 2;//落在两个六边形上
area2_1 = AREA / 6 - area2_2;//落在一个六边形上
//与三个六边形相邻的顶点
area3_3 = R*R*(PI / 6 + 1 / SQRT3);//落在三个六边形上
area3_1 = (0.5 - R / SQRT3)*(SQRT3 / 2 - R);//落在一个六边形上
area3_2 = AREA / 6 - area3_1 - area3_3;//落在两个六边形上
point3 = (2 * N - 3)*(M - 1);
if (M % 2 == 0) {//偶数行
point1 = (N + M + 1) * 2 - 1;
point2 = (N + M - 2) * 2 - 1;
}
else {//奇数行
point1 = (K + M + 1) * 2;
point2 = (K + M - 2) * 2;
}
count = N*M - M / 2;
if (K < N && M % 2 == 1) count--;
area = count*AREA;
area1 = point1*area1_1 + point2*area2_1 * 2 + point3*area3_1 * 3;
area2 = point2*area2_2 * 2 + point3*area3_2 * 3;
area3 = point3*area3_3 * 3;
printf("Case %d:\n", T++);
printf("Probability of covering 1 hexagon = %.3llf percent.\n", area1 / area * 100);
printf("Probability of covering 2 hexagons = %.3llf percent.\n", area2 / area * 100);
printf("Probability of covering 3 hexagons = %.3llf percent.\n", area3 / area * 100);
printf("\n");
}
return 0;
}
POJ_3766_Hexagon Coin Toss
最新推荐文章于 2020-03-06 15:47:33 发布