結果

問題 No.3031 (物理学)長距離相互作用
ユーザー 37zigen37zigen
提出日時 2016-10-12 19:30:24
言語 Java21
(openjdk 21)
結果
AC  
実行時間 132 ms / 10,000 ms
コード長 4,809 bytes
コンパイル時間 2,313 ms
コンパイル使用メモリ 75,916 KB
実行使用メモリ 56,624 KB
最終ジャッジ日時 2023-08-26 19:12:18
合計ジャッジ時間 4,216 ms
ジャッジサーバーID
(参考情報)
judge11 / judge12
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 129 ms
55,932 KB
testcase_01 AC 132 ms
56,156 KB
testcase_02 AC 125 ms
56,544 KB
testcase_03 AC 132 ms
55,908 KB
testcase_04 AC 129 ms
56,132 KB
testcase_05 AC 127 ms
56,048 KB
testcase_06 AC 126 ms
56,020 KB
testcase_07 AC 129 ms
56,624 KB
testcase_08 AC 125 ms
56,188 KB
testcase_09 AC 123 ms
56,192 KB
testcase_10 AC 120 ms
56,172 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

import java.util.Scanner;
public class Main{
	public static void main(String[] args) {
		new Main().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;
		double[] in = new double[16];
		for (int i = 0; i < 16; i++) {
			in[i] = sc.nextDouble();
			assert Math.abs(in[i]) >= 0 && Math.abs(in[i]) <= 5;
		}
		A += in[0];
		B += in[1];
		B += in[2];
		C += in[3];
		B += in[4];
		C += in[5];
		C += in[6];
		D += in[7];
		for (int i = 0; i < 8; i++) {
			E += in[i + 8];
		}

		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] };
	}
}
0