結果
| 問題 |
No.8031 (物理学)長距離相互作用
|
| ユーザー |
|
| 提出日時 | 2016-09-09 12:56:43 |
| 言語 | Java (openjdk 23) |
| 結果 |
AC
|
| 実行時間 | 155 ms / 10,000 ms |
| コード長 | 4,770 bytes |
| コンパイル時間 | 3,522 ms |
| コンパイル使用メモリ | 79,492 KB |
| 実行使用メモリ | 41,712 KB |
| 最終ジャッジ日時 | 2024-12-25 20:26:50 |
| 合計ジャッジ時間 | 5,801 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 11 |
ソースコード
package 作問;
import java.util.Scanner;
public class Q001_answer {
public static void main(String[] args) {
new Q001_answer().solver();
}
void solver() {
// double constant_of_NaCl = calculator(0) * 2;
// double constant_of_CsCl = calculator(1);
double constant_of_NaCl = -3.4951291900072743;
double constant_of_CsCl = -2.0353641336977053;
Scanner sc = new Scanner(System.in);
double A = 0, B = 0, C = 0, D = 0, E = 0;
A += sc.nextDouble();
B += sc.nextDouble();
B += sc.nextDouble();
C += sc.nextDouble();
B += sc.nextDouble();
C += sc.nextDouble();
C += sc.nextDouble();
D += sc.nextDouble();
for (int i = 0; i < 8; i++)
E += sc.nextDouble();
assert 4 * (A + D) + E == 0;
assert (A + B + C + D + E) == 0;
final double m100 = -1.0 / 6.0 * constant_of_NaCl + 1.0 / 3.0 * constant_of_CsCl;
final double m110 = 1.0 / 6.0 * constant_of_NaCl;
System.out.println((3 * A + B) * m100 + (3 * A + C) * m110);
}
double[][] make_sample_of_NaCl() {
double[][] p = new double[4][27];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 3; k++) {
p[0][(9 * i + 3 * j + k)] = i;
p[1][(9 * i + 3 * j + k)] = j;
p[2][(9 * i + 3 * j + k)] = k;
p[3][(9 * i + 3 * j + k)] = (i + j + k) % 2 == 0 ? 1 : -1;
}
}
}
return p;
}
// NaCl:0
// CsCl:1
double calculator(int isNaClorCsCl) {
double[][] p = make_sample_of_NaCl();
double[][] axis = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };
if (isNaClorCsCl == 1)
axis = new double[][] { { 0.5, 0.5, -0.5 }, { -0.5, 0.5, 0.5 }, { 0.5, -0.5, 0.5 } };
double sum = 0;
// p1 and p2 show the point of the cell.
// for (int i = 0; i <= 50; i++) {
// for (int p1 = 0; p1 <= i; p1++) {
// for (int p2 = 0; p2 <= i; p2++) {
// sum += calc(p1, p2, i, p, axis);
// sum += calc(p2, i, p1, p, axis);
// sum += calc(i, p1, p2, p, axis);
// }
// sum -= calc(i, i, p1, p, axis);
// sum -= calc(i, p1, i, p, axis);
// sum -= calc(p1, i, i, p, axis);
// }
// sum += calc(i, i, i, p, axis);
// }
for (int i = isNaClorCsCl == 0 ? 0 : -50; i <= 50; i++) {
for (int j = isNaClorCsCl == 0 ? 0 : -50; j <= 50; j++) {
for (int k = 0; k <= 50; k++) {
sum += calc(i, j, k, p, axis);
}
}
}
return sum * (isNaClorCsCl == 0 ? 8 : 2);
}
double calc(int nx, int ny, int nz, double[][] p, double[][] axis) {
double sum = 0;
int n = p[0].length;
for (int i = 0; i < n; i++) {
double x = 2 * nx + p[0][i];
double y = 2 * ny + p[1][i];
double z = 2 * nz + p[2][i];
if (x == 0 && y == 0 && z == 0)
continue;
double coe = 1;
if ((p[0][i] == 2 || p[0][i] == 0) && (p[1][i] == 2 || p[1][i] == 0) && (p[2][i] == 2 || p[2][i] == 0))
coe *= solid_angle(p[0][i] == 2 ? vector_minus(axis[0]) : axis[0],
p[1][i] == 2 ? vector_minus(axis[1]) : axis[1], p[2][i] == 2 ? vector_minus(axis[2]) : axis[2])
/ (4 * Math.PI);
else if (((p[0][i] == 2 || p[0][i] == 0) && (p[1][i] == 2 || p[1][i] == 0))
|| ((p[1][i] == 2 || p[1][i] == 0) && (p[2][i] == 2 || p[2][i] == 0))
|| ((p[2][i] == 2 || p[2][i] == 0) && (p[0][i] == 2 || p[0][i] == 0))) {
double[][] v = new double[2][3];
int c = 0;
for (int j = 0; j < 3; j++) {
if (p[j][i] == 2 || p[j][i] == 0) {
if (p[j][i] == 2)
v[c++] = vector_minus(axis[j]);
else
v[c++] = axis[j];
}
}
coe *= dihedral_angle(v[0], v[1]) / (2 * Math.PI);
} else if ((p[0][i] == 2 || p[0][i] == 0) || (p[1][i] == 2 || p[1][i] == 0)
|| (p[2][i] == 2 || p[2][i] == 0))
coe *= 0.5;
sum += p[3][i] / dist(0, 0, 0, x, y, z, axis) * coe;
}
return sum;
}
double dist(double x1, double y1, double z1, double x2, double y2, double z2, double[][] axis) {
return Math.sqrt((x1 - x2) * (x1 - x2) * dot_product(axis[0], axis[0])
+ (y1 - y2) * (y1 - y2) * dot_product(axis[1], axis[1])
+ (z1 - z2) * (z1 - z2) * dot_product(axis[2], axis[2])
+ dot_product(axis[0], axis[1]) * 2 * (x1 - x2) * (y1 - y2)
+ dot_product(axis[1], axis[2]) * 2 * (y1 - y2) * (z1 - z2)
+ dot_product(axis[2], axis[0]) * 2 * (z1 - z2) * (x1 - x2));
}
double dot_product(double[] p, double[] q) {
double ret = 0;
for (int i = 0; i < 3; i++) {
ret += p[i] * q[i];
}
return ret;
}
double dihedral_angle(double[] p, double[] q) {
return Math.acos(dot_product(p, q) / (vector_length(p) * vector_length(q)));
}
double vector_length(double[] p) {
return Math.sqrt(dot_product(p, p));
}
double solid_angle(double[] v1, double[] v2, double[] v3) {
return dihedral_angle(v1, v2) + dihedral_angle(v2, v3) + dihedral_angle(v3, v1) - Math.PI;
}
double[] vector_minus(double[] v) {
return new double[] { -v[0], -v[1], -v[2] };
}
}