列表

详情


NC232573. NuclearReactor

描述

谷宝最近在研究IndustrialCraft2(IC2)的核反应堆,但是技巧并不娴熟的他经常发生堆芯熔毁炸掉基地。他在Wiki上找到了核反应堆各组件的属性说明提供给你,希望你帮他做一个核反应堆运行模拟器判断他设计的核反应堆能否安全运行一个周期。

IC2的核反应堆设置界面为一个的网格,每个网格可以放置一个组件或者空置。核反应堆本身在运行中可以至多吸纳10000点热量,当热量超限时就会发生堆芯熔毁的爆炸奇观。

为了方便收集材料,谷宝的核反应堆只打算使用三种组件——铀燃料棒、中子反射板和散热片。

全新的铀燃料棒可以运行20000秒,即一个周期。铀燃料棒可以联合为双联燃料棒或者四联燃料棒使用以节约空间。在运行时,铀燃料棒会向相邻的四个网格中各发射1个中子,联合燃料棒发射的中子数随联数增加至2个或4个。同时,燃料棒的热量会平均分配给相邻的A类散热片,A类散热片无法吸收的热量会成为核反应堆自身的热量。

设燃料棒的发电量为W,发热量为Q,接收中子数为n,联数为m,基础效率系数为,那么有



其中,m的取值为124,对应的基础效率系数为123

中子反射板自身不产生任何电量或热量,但是它会将接收到的中子反射回燃料棒。

散热片共有三大类,散热片具有最大吸热速度、最大散热速度和热量缓存(除C类散热片)。

A类散热片会吸收相邻燃料棒的热量,其最大吸热速度和最大散热速度相等。普通的A类散热片热交换速度为6点每秒,而高级的A类散热片热交换速度为12点每秒。由于最大吸热速度和最大散热速度相等,当A类散热片与超过一个燃料棒相邻时可能会无法全部散去吸收的热量,当热量超过1000点时自身会熔毁,熔毁时,超过部分的热量不会进入核反应堆的热量缓存。

B类散热片会吸收核反应堆自身的热量。普通的B类散热片每秒最多吸收并散去5点热量。高级的B类散热片则每秒最多吸收32点热量并散去20点热量,当热量超过1000点时自身会熔毁,熔毁时,超出部分的热量不会进入核反应堆的热量缓存。核反应堆可以智能调控B类散热片,保证同种B类散热片吸收的热量是相等的并且普通的B类散热片会被优先使用,以达到最大化利用B类散热片的目的。此外,B类散热片只能吸收已有的核反应堆热量,换言之,某一时刻进入核反应堆热量缓存的热量至少要到下一时刻才可以被散去。

C类散热片用于协助另外两类散热片工作,每秒最多可以散去每个相邻的其他散热片4点热量。

为了简化问题,核反应堆不存在启动问题,即第一秒时燃料棒就可以接收到来自相邻燃料棒和中子反射板的中子。此外,不考虑散热片和核反应堆某一时刻由于热量超限无法接收该时刻热量的问题,换言之,热交换的结算先于熔毁。

输入描述

一个六行九列的网格,每个网格包含一个字符表示该网格内的组件情况。
“#”代表空,“U”表示铀燃料棒,“D”表示双联燃料棒,“Q”表示四联燃料棒,“N”表示中子反射板,“A”表示高级的A类散热片,“a”表示普通的A类散热片,“B”表示高级的B类散热片,“b”表示普通的B类散热片,“C”表示C类散热片。

输出描述

1、是否会发生熔毁,如果会熔毁,则在第一行输出Boom!,若可以安全运行一个周期,则给出运行结束时核反应堆的热量(保留两位小数)。
2、熔毁时或运行结束时的总发电量。

示例1

输入:

BBNNCaCaN
NDQBbUa#N
AQAQQNNU#
AUAQ#QAQN
QDNCNNUCB
QQNUbUaCa

输出:

Boom!
4550

示例2

输入:

#########
#########
##ADA####
###a#####
#########
#########

输出:

Boom!
100020

示例3

输入:

#########
###UaU###
#########
#########
#########
#########

输出:

Boom!
17520

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 10ms, 内存消耗: 456K, 提交时间: 2023-01-13 11:51:57

#include <iostream>
#include <cstring>
#include <algorithm>
#include <iomanip>
 
using namespace std;
 
const int MAXX = 6 + 2;
const int MAXY = 9 + 2;
const int MAXTemp = 10000;
const int MAXTime = 20000;
const int MAXVentTemp = 1000;
 
const int dx[4] {0, -1, 0, 1};
 
const int dy[4] {-1, 0, 1, 0};
 
char map[MAXX][MAXY];
long long mapRodHeat[MAXX][MAXY];
double mapVentHeat[MAXX][MAXY];
long long mapVentANum[MAXX][MAXY];
long long ventBNum, ventbNum;
long long mapVentCNum[MAXX][MAXY];
 
int main() {
	memset(map, 0, sizeof(map));
	for (int i = 1; i < MAXX - 1; ++i) {
		for (int j = 1; j < MAXY - 1; ++j) {
			map[i][j] = getchar();
		}
		getchar();
	}
 
	long long answ = 0;
	memset(mapRodHeat, 0, sizeof(mapRodHeat));
	memset(mapVentANum, 0, sizeof(mapVentANum));
	memset(mapVentCNum, 0, sizeof(mapVentCNum));
	for (int i = 1; i < MAXX - 1; ++i) {
		for (int j = 1; j < MAXY - 1; ++j) {
			if (map[i][j] == 'U' || map[i][j] == 'D' || map[i][j] == 'Q') {
				int n = 0, m = 1, eta = 1;
				if (map[i][j] == 'D') {
					m = 2;
					eta = 2;
				} else if (map[i][j] == 'Q') {
					m = 4;
					eta = 3;
				}
				for (int di = 0; di < 4; ++di) {
					if (map[i + dx[di]][j + dy[di]] == 'U') {
						n += 1;
					} else if (map[i + dx[di]][j + dy[di]] == 'D') {
						n += 2;
					} else if (map[i + dx[di]][j + dy[di]] == 'Q') {
						n += 4;
					} else if (map[i + dx[di]][j + dy[di]] == 'N') {
						n += m;
					}
				}
				answ += 5 * m * (eta + n);
				mapRodHeat[i][j] = 2 * m * (eta + n) * (eta + n + 1);
			} else if (map[i][j] == 'A' || map[i][j] == 'a') {
				for (int di = 0; di < 4; ++di) {
					++mapVentANum[i + dx[di]][j + dy[di]];
				}
			} else if (map[i][j] == 'B') {
				++ventBNum;
			} else if (map[i][j] == 'b') {
				++ventbNum;
			} else if (map[i][j] == 'C') {
				for (int di = 0; di < 4; ++di) {
					++mapVentCNum[i + dx[di]][j + dy[di]];
				}
			}
		}
	}
 
	long long ansW = 0;
	double ansQ = 0;
	bool isBoom = 0;
	memset(mapVentHeat, 0, sizeof(mapVentHeat));
	for (int k = 0; k < MAXTime; ++k) {
		ansW += answ;
		ansQ = max((double)0, ansQ - (5 * ventbNum));
		double heatToVentB = ansQ;
		if (ventBNum != 0)
			ansQ = 0;
		for (int i = 1; i < MAXX - 1; ++i) {
			for (int j = 1; j < MAXY - 1; ++j) {
				if (mapRodHeat[i][j] != 0 && mapVentANum[i][j] == 0) {
					ansQ += mapRodHeat[i][j];
				} else if (mapVentHeat[i][j] > MAXVentTemp)
					continue;
				else if (map[i][j] == 'A') {
					for (int di = 0; di < 4; ++di) {
						if (mapRodHeat[i + dx[di]][j + dy[di]] != 0) {
							mapVentHeat[i][j] += min((double)12, (double)mapRodHeat[i + dx[di]][j + dy[di]] / mapVentANum[i + dx[di]][j + dy[di]]);
							ansQ += max((double)0, (double)mapRodHeat[i + dx[di]][j + dy[di]] / mapVentANum[i + dx[di]][j + dy[di]] - 12);
						}
					}
				} else if (map[i][j] == 'a') {
					for (int di = 0; di < 4; ++di) {
						if (mapRodHeat[i + dx[di]][j + dy[di]] != 0) {
							mapVentHeat[i][j] += min((double)6, (double)mapRodHeat[i + dx[di]][j + dy[di]] / mapVentANum[i + dx[di]][j + dy[di]]);
							ansQ += max((double)0, (double)mapRodHeat[i + dx[di]][j + dy[di]] / mapVentANum[i + dx[di]][j + dy[di]] - 6);
						}
					}
				} else if (map[i][j] == 'B') {
					mapVentHeat[i][j] += min((double)32, (double)heatToVentB / ventBNum);
					ansQ += max((double)0, (double)heatToVentB / ventBNum - 32);
				}
			}
		}
		for (int i = 1; i < MAXX - 1; ++i) {
			for (int j = 1; j < MAXY - 1; ++j) {
				if (mapVentHeat[i][j] > MAXVentTemp + 10000)
					continue;
				else if (map[i][j] == 'A') {
					mapVentHeat[i][j] = max((double)0, mapVentHeat[i][j] - 12 - 4 * mapVentCNum[i][j]);
					if (mapVentHeat[i][j] > MAXVentTemp) {
						mapVentHeat[i][j] += 10000;
						for (int di = 0; di < 4; ++di) {
							--mapVentANum[i + dx[di]][j + dy[di]];
						}
					}
				} else if (map[i][j] == 'a') {
					mapVentHeat[i][j] = max((double)0, mapVentHeat[i][j] - 6 - 4 * mapVentCNum[i][j]);
					if (mapVentHeat[i][j] > MAXVentTemp) {
						mapVentHeat[i][j] += 10000;
						for (int di = 0; di < 4; ++di) {
							--mapVentANum[i + dx[di]][j + dy[di]];
						}
					}
				} else if (map[i][j] == 'B') {
					mapVentHeat[i][j] = max((double)0, mapVentHeat[i][j] - 20 - 4 * mapVentCNum[i][j]);
					if (mapVentHeat[i][j] > MAXVentTemp) {
						mapVentHeat[i][j] += 10000;
						--ventBNum;
					}
				}
			}
		}
		if (ansQ > MAXTemp) {
			isBoom = 1;
			break;
		}
	}
 
	if (isBoom)
		cout << "Boom!";
	else
		printf("%.2lf", ansQ);
	cout << endl << ansW << endl;
 
	return 0;
}

C++ 解法, 执行用时: 9ms, 内存消耗: 444K, 提交时间: 2022-01-16 18:01:53

#include<bits/stdc++.h>
using namespace std;
vector<pair<int,int> >d={{0,1},{0,-1},{1,0},{-1,0}};
int i,j,k,n,m,t,res,dian,cb1,cb2;
int f[66][66],zz[66][66],w[66][66];
double q[66][66],g[66][66],tot;
double re;
#define rep for(i=1;i<=6;i++)for(j=1;j<=9;j++)
string s="#UDQNAaBbC";
int main() {
	rep{
		char c=getchar();
		for(k=0;k<=9;k++)if(c==s[k]){f[i][j]=k,cb2+=(k==7),cb1+=(k==8);break;}
		if(k>9)j--;
	}
	rep if(f[i][j]>=1&&f[i][j]<=3){
			for(auto [dx,dy]:d){
				dx+=i;dy+=j;
				if(f[dx][dy]==4)zz[i][j]+=(1<<(f[i][j]-1));
				else zz[dx][dy]+=(1<<(f[i][j]-1));
			}
		}
	rep if(f[i][j]>=1&&f[i][j]<=3){
			w[i][j]=5*(1<<(f[i][j]-1))*(zz[i][j]+f[i][j]);
			q[i][j]=2*(1<<(f[i][j]-1))*(zz[i][j]+f[i][j])*(1+zz[i][j]+f[i][j]);
			dian+=w[i][j];
		}
	for(t=1;t<=20000;t++){
		re=max(0.0,re-cb1*5);
		double tmp=min(32.0,re/max(cb2,1));
		rep{
			if(f[i][j]==7)g[i][j]+=tmp,re-=tmp,g[i][j]=max(0.0,g[i][j]-20);
		}
		rep{
			k=0;tot=0;
			if(f[i][j]>=1&&f[i][j]<=3){
				for(auto [dx,dy]:d){
					dx+=i;dy+=j;
					if(f[dx][dy]==5||f[dx][dy]==6)k++;
				}
				if(!k){re+=q[i][j];continue;}
				tot=q[i][j]/k;
				for(auto [dx,dy]:d){
					dx+=i;dy+=j;
					if(f[dx][dy]==5)g[dx][dy]+=min(12.0,tot),re+=max(0.0,tot-12.0);
					if(f[dx][dy]==6)g[dx][dy]+=min(6.0,tot),re+=max(0.0,tot-6.0);
				}
			}
		}
		rep{
			if(f[i][j]==5)g[i][j]=max(0.0,g[i][j]-12);
			if(f[i][j]==6)g[i][j]=max(0.0,g[i][j]-6);
			if(f[i][j]==9)for(auto [dx,dy]:d){
				dx+=i;dy+=j;
				g[dx][dy]=max(0.0,g[dx][dy]-4);
			}
		}
		rep{
			if(f[i][j]>=5&&f[i][j]<=6&&g[i][j]>1000)f[i][j]=0;
			if(f[i][j]==7&&g[i][j]>1000)f[i][j]=0,cb2--;
		}
		if(re>10000)return printf("Boom!\n%d",t*dian),0;
	}
	printf("%.2lf\n%d",re,dian*20000);
}

上一题