UVA-221 Urban Elevations(离散化)

本文详细解析了一种用于判断从特定视角哪些建筑可见的算法。通过保存并处理建筑边界坐标,实现建筑排序与去重,进而判断建筑是否被遮挡。核心思路包括使用x数组记录边界、排序和枚举检查每个建筑的可见性。

题意:

给出建筑左下角的坐标和建筑的宽度(w)、高度(h)、长度(d),判断从南往北看,哪些建筑可以能够看到。

思路:

将建筑的左边界和右边界用一个x数组保存下来,然后按照题目要求进行排序、去重。

这样处理之后的x数组中相邻两个数表示的区间是从南往北可以看到的。

枚举每一个建筑,然后在这个建筑的基础上枚举每一个可以看到的区间,在这基础上在枚举判断这个建筑是不是被其他的建筑给挡住了,没有就输出这个建筑的id。

 

看图可以理解对x数组进行排序去重的操作。

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define MAX 1e9;
#define FRE() freopen("in.txt","r",stdin)
#define FRO() freopen("out.txt","w",stdout)
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
const int maxn = 300;
struct Build{
    double x,y,w,d,h;
    int id;
    bool operator<(const Build& bb)const{
        return x<bb.x || (x==bb.x && y<bb.y);
    }
}b[maxn];
double x[2*maxn];
int n;

bool Cover(int idx, double mx){//判断这个建筑的宽度内有没有这个中点mx
    return b[idx].x<=mx && (b[idx].x+b[idx].w)>=mx;
}

bool Visiable(int idx, double mx){
    if(!Cover(idx,mx))return false;//如果这个建筑的宽度内没有这个中点,就直接返回看不到
    for(int i = 0; i<n; i++){
        if(b[i].y<b[idx].y && b[i].h>=b[idx].h && Cover(i,mx)){
            return false;
        }
    }
    return true;
}

int main(){
    int cnt = 0;
    while(cin>>n&&n){
        for(int i = 0; i<n; i++){
            cin>>b[i].x>>b[i].y>>b[i].w>>b[i].d>>b[i].h;
            x[i*2] = b[i].x;//用x数组保存建筑的左边界
            x[i*2+1] = b[i].x+b[i].w;//用x数组保存建筑的右边界
            b[i].id = i+1;
        }
        sort(b,b+n);//对建筑按照题目的要求进行排序
        sort(x,x+2*n);//对x数组从小到大进行排序
        int m = unique(x,x+n*2)-x;//获得m个可以看到的区间,相邻的两个x数组的数表示一个区间
        if(cnt++){
            cout<<endl;
        }
        cout<<"For map #"<<cnt<<", the visible buildings are numbered as follows:"<<endl;
        cout<<b[0].id;//位于最左下角的建筑一定是可以看到的
        for(int i=1; i<n; i++){//枚举每一个建筑
            for(int j=0; j<m-1; j++){//枚举每一个可以看到的区间
                if(b[i].x>x[j] || b[i].x+b[i].w<x[j+1])continue;//如果这个建筑直接不出现在这个区间中,就直接跳过
                if(Visiable(i, (x[j]+x[j+1])/2.0)){//如果能看见就输出
                                                    //任取区间中的一个点(中点),如果建筑的宽度中有这个点
                    cout<<" "<<b[i].id;
                    break;
                }
            }
        }
        cout<<endl;
    }
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/sykline/p/10273316.html

model HeatingSystem // 系统参数 parameter Integer nPipes = 2 "供水管+回水管"; parameter Integer nNodes = 3 "泵出口、用户入口、回水出口"; // 管道参数 parameter Real pipe_lengths[nPipes] = {500, 500} "管道长度(m)"; parameter Real pipe_diameters[nPipes] = {0.08, 0.1} "管道直径(m)"; parameter Real pipe_roughness[nPipes] = {4.5e-5, 4.5e-5} "粗糙度(m)"; parameter Real local_loss_coeffs[nPipes] = {0.5, 0.3} "局部损失系数"; // 流体属性 parameter Real fluid_density = 983.2 "密度(kg/m³)"; parameter Real fluid_viscosity = 0.00046 "粘度(Pa·s)"; // 节参数 parameter Real node_elevations[nNodes] = {45.2, 42.0, 40.5} "节高度(m)"; // 泵参数 parameter Real pump_head_input = 32 "泵扬程(m)"; // 主要变量 Real flow_rate( start = 0.018, fixed = false, min = 1e-6, nominal = 0.02 ) "系统流量(m³/s)"; Real pressure_losses[nPipes] "管路压降(Pa)"; Real node_pressures[nNodes] "节压力(Pa)"; // 中间变量 Real Re[nPipes] "雷诺数"; Real f[nPipes] "摩擦系数"; Real v[nPipes] "管道流速(m/s)"; Real area[nPipes] "管道横截面积(m&sup2;)"; Real v_safe[nPipes] "安全流速(m/s)"; Real pumpPower "泵功率(W)"; Real lossPower "损失功率(W)"; Real elevationPower "高程功率(W)"; Real balance "能量平衡(W)"; // 常量 constant Real g = Modelica.Constants.g_n "重力加速度"; constant Real pi = Modelica.Constants.pi "圆周率"; constant Real p_atm = 101325 "标准大气压(pa)"; // 系统动态参数 parameter Real timeConstant = 10 "系统时间常数"; parameter Real pipeInertia = 10000 "管道流体惯性(kg/m)"; // 摩擦系数计算函数 function calculateFrictionFactor input Real Re; input Real eps; // 相对粗糙度 output Real f; protected Real Re_safe = max(Re, 1e-3); Real log_arg, A, B; algorithm if Re_safe <= 2300 then f := 64 / Re_safe; else // 数值稳定Churchill公式 log_arg := max((7/Re_safe)^0.9 + 0.27*eps, 1e-10); A := (-2.457 * log(log_arg))^16; B := max((37530/Re_safe)^16, 1e-16); f := 8 * ((8/Re_safe)^12 + 1/max((A+B)^1.5, 1e-10))^(1/12); end if; // 确保摩擦系数在合理范围内 f := min(max(f, 0.001), 0.1); end calculateFrictionFactor; initial equation der(flow_rate) = 0; // 稳态初始化 sum(pressure_losses) = pump_head_input * fluid_density * g - fluid_density * g * (node_elevations[1] - node_elevations[3]); equation /* ===== 核心物理模型 ===== */ /* 节压力计算 */ node_pressures[1] = pump_head_input * fluid_density * g + 101325 + node_elevations[1] * fluid_density * g; node_pressures[2] = node_pressures[1] - pressure_losses[1]; node_pressures[3] = 101325 + node_elevations[3] * fluid_density * g; /* 预计算管道面积 */ for i in 1:nPipes loop area[i] = pi * (pipe_diameters[i]/2)^2; end for; /* 压力损失计算 */ for i in 1:nPipes loop // 雷诺数 Re[i] = fluid_density * noEvent(smooth(1, if flow_rate > 1e-6 then flow_rate else 1e-6)) * pipe_diameters[i] / max(fluid_viscosity, 1e-10); // 摩擦系数 f[i] = calculateFrictionFactor(Re[i], pipe_roughness[i]/pipe_diameters[i]); // 流速 v[i] = noEvent(smooth(1, if abs(flow_rate) > 1e-6 then flow_rate / area[i] else 0)); // 安全流速 v_safe[i] = noEvent(smooth(1, if abs(v[i]) > 0.01 then abs(v[i]) else 0.01)); // 压力损失 (关键修复:添加平滑过渡) pressure_losses[i] = noEvent(smooth(1, (f[i] * pipe_lengths[i] / pipe_diameters[i] + local_loss_coeffs[i]) * 0.5 * fluid_density * v_safe[i]^2 * sign(flow_rate) )); end for; /* 流体动力学方程 (关键修复:添加平滑过渡) */ pipeInertia * der(flow_rate) = pump_head_input * fluid_density * g - sum(pressure_losses) - fluid_density * g * (node_elevations[1] - node_elevations[3]) + noEvent(if flow_rate < 1e-5 then 1e-3 else 0); /* ===== 监控与验证 ===== */ // 容差验证(1 Pa容差) assert(node_pressures[1] > node_pressures[2] + 1, "供水管压力递减: " + String(node_pressures[1]) + " > " + String(node_pressures[2])); assert(node_pressures[2] > node_pressures[3] + 1, "回水管压力递减: " + String(node_pressures[2]) + " > " + String(node_pressures[3])); assert(flow_rate > 1e-5, "流量为正: " + String(flow_rate)); // 添加能量守恒验证 pumpPower = flow_rate * (node_pressures[1] - p_atm); lossPower = sum(pressure_losses) * abs(flow_rate); elevationPower = fluid_density * g * (node_elevations[1] - node_elevations[3]) * flow_rate; balance = pumpPower - lossPower - elevationPower; assert(abs(balance) < 10, "能量不平衡: " + String(balance) + " W"); end HeatingSystem; 仿真失败,退出码 0xffffffffffffffff 。 C:/Users/lancable/AppData/Local/Temp/OpenModelica/OMEdit/HeatingSystem/HeatingSystem.exe -port=57084 -logFormat=xmltcp -override=startTime=0,stopTime=1,stepSize=0.002,tolerance=1e-06,solver=dassl,outputFormat=mat,variableFilter=.* -r=C:/Users/lancable/AppData/Local/Temp/OpenModelica/OMEdit/HeatingSystem/HeatingSystem_res.mat -w -lv=LOG_STDOUT,LOG_ASSERT,LOG_STATS -inputPath=C:/Users/lancable/AppData/Local/Temp/OpenModelica/OMEdit/HeatingSystem -outputPath=C:/Users/lancable/AppData/Local/Temp/OpenModelica/OMEdit/HeatingSystem The following assertion has been violated during initialization at time 0.000000 ((abs(balance) < 10.0)) --> "能量不平衡: 1994.99 W" simulation terminated by an assertion at initialization
09-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值