[二维区间DP?] Atcoder ARC004E. Salvage Robots

本文介绍了一种通过移动出口位置来最大化救援机器人的算法。利用二维矩阵记录障碍物分布,并通过动态规划方法计算不同出口位置下可救援的最大机器人数量。算法涉及四个方向上的状态转移。

可以让出口移动,robots不动
fu,d,l,r 表示出口活动的区域为 (xu,yl)(x+d,y+r) 这个矩形时最多能救多少机器人。转移的话,画画图可以知道哪些区域求不了

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N=105;

int n,m,x,y,L[N][N],R[N][N];
char a[N][N];

short f[N][N][N][N],ans;

inline void fix(short &x,short y){
  if(x<y) x=y;
}

int main(){
  freopen("1.in","r",stdin);
  freopen("1.out","w",stdout);
  scanf("%d%d",&n,&m);
  for(int i=1;i<=n;i++){
    scanf("%s",a[i]+1);
    for(int j=1;j<=m;j++){
      if(a[i][j]=='E') x=i,y=j;
      L[i][j]=L[i][j-1]+(a[i][j]=='o');
      R[i][j]=R[i-1][j]+(a[i][j]=='o');
    }
  }
  memset(f,-0x7f,sizeof(f)); f[0][0][0][0]=0;
  for(int u=0;x-u>0;u++)
    for(int d=0;x+d<=n;d++)
      for(int l=0;y-l>0;l++)
    for(int r=0;y+r<=m;r++){
      if(f[u][d][l][r]<0) continue;
      short cur=f[u][d][l][r]; ans=max(ans,cur);
      if(x-d>u+1 && x-u-1>0)
        fix(f[u+1][d][l][r],cur+L[x-u-1][min(y+r,m-l)]-L[x-u-1][max(y-l-1,r)]);
      if(x+u+d<n && x+d+1<=n)
        fix(f[u][d+1][l][r],cur+L[x+d+1][min(y+r,m-l)]-L[x+d+1][max(y-l-1,r)]);
      if(y+l+r<m && y+r+1<=m)
        fix(f[u][d][l][r+1],cur+R[min(x+d,n-u)][y+r+1]-R[max(x-u-1,d)][y+r+1]);
      if(y-r>l+1 && y-l-1>0)
        fix(f[u][d][l+1][r],cur+R[min(x+d,n-u)][y-l-1]-R[max(x-u-1,d)][y-l-1]);
    }
  printf("%d\n",(int)ans);
  return 0;
}
要检测一个 `.b3dm` 文件是否包含有效的 PBR(Physically Based Rendering)材质信息,我们需要理解 `.b3dm` 的结构:它是一个容器格式,内部封装了一个 **glTF 2.0 的二进制版本(`.glb`)**。因此,关键在于提取并解析这个嵌入的 `.glb` 中的 `materials` 是否符合 glTF 2.0 的 PBR 标准。 --- ### ✅ 检测目标 我们希望确认以下几点: 1. 是否存在 `pbrMetallicRoughness` 属性? 2. 是否定义了 `baseColorTexture` 或 `metallicRoughnessTexture`? 3. 材质是否有纹理引用且未丢失? 4. 是否使用已被弃用的旧技术(如 `KHR_techniques_webgl`)? --- ## ✅ 方法一:使用 Python 解析 .b3dm 并检查 GLB 内容(推荐) 下面是一个完整的 Python 脚本,用于: - 读取 `.b3dm` 头部 - 提取内部 `.glb` 数据 - 解码 JSON 部分 - 检查是否存在标准 PBR 材质 ```python import struct import json import sys from typing import Dict, Any def parse_b3dm_pbr_info(b3dm_path: str): """ 分析 .b3dm 文件中的 GLB 是否包含有效的 PBR 材质信息 """ with open(b3dm_path, 'rb') as f: # 读取 b3dm header (28 字节) magic = f.read(4).decode('utf-8') if magic != "b3dm": raise ValueError("Not a valid B3DM file") version = struct.unpack('I', f.read(4))[0] byteLength = struct.unpack('I', f.read(4))[0] featureTableJSONByteLength = struct.unpack('I', f.read(4))[0] featureTableBinaryByteLength = struct.unpack('I', f.read(4))[0] batchTableJSONByteLength = struct.unpack('I', f.read(4))[0] batchTableBinaryByteLength = struct.unpack('I', f.read(4))[0] print(f"B3DM Version: {version}, Total Length: {byteLength}") print(f"Feature Table JSON: {featureTableJSONByteLength}") print(f"Batch Table JSON: {batchTableJSONByteLength}") # 计算 GLB 起始位置 glb_start = ( 28 + featureTableJSONByteLength + featureTableBinaryByteLength + batchTableJSONByteLength + batchTableBinaryByteLength ) f.seek(glb_start) # 现在读取嵌入的 GLB return parse_glb_for_pbr(f) def parse_glb_for_pbr(file_obj) -> Dict[str, Any]: """ 解析 GLB 流并返回 PBR 材质信息 """ # GLB Header magic = file_obj.read(4).hex() if magic != '676c5446': # 'glTF' raise ValueError("Embedded data is not a valid GLB") version = struct.unpack('I', file_obj.read(4))[0] length = struct.unpack('I', file_obj.read(4))[0] print(f"GLB Version: {version}") # 解析 chunks json_chunk = None bin_chunk = None while True: try: chunk_length = struct.unpack('I', file_obj.read(4))[0] chunk_type = file_obj.read(4).hex() if chunk_type == '4e4f534a': # JSON chunk ('JSON') json_chunk_data = file_obj.read(chunk_length) json_chunk = json.loads(json_chunk_data.decode('utf-8')) elif chunk_type == '004e4942': # BIN chunk ('BIN\0') file_obj.seek(chunk_length, 1) # skip binary data bin_chunk = True else: print(f"Unknown chunk type: {chunk_type}") file_obj.seek(chunk_length, 1) except Exception as e: break if file_obj.tell() >= length + 12: # 12 = GLB header size break if not json_chunk: raise ValueError("No JSON chunk found in GLB") # 检查材质 materials = json_chunk.get("materials", []) has_pbr = False has_base_color_texture = False uses_deprecated_ext = False for i, mat in enumerate(materials): print(f"\nMaterial {i}: {mat.get('name', 'Unnamed')}") # 检查 PBR Metallic-Roughness pbr = mat.get("pbrMetallicRoughness") if pbr: has_pbr = True print(" ✅ Uses pbrMetallicRoughness") base_color_tex = pbr.get("baseColorTexture") if base_color_tex: has_base_color_texture = True print(f" 🖼️ Has baseColorTexture (index: {base_color_tex['index']})") else: print(" ⚠️ No baseColorTexture (may be flat color)") metallic_roughness_tex = pbr.get("metallicRoughnessTexture") if metallic_roughness_tex: print(f" 🖼️ Has metallicRoughnessTexture (index: {metallic_roughness_tex['index']})") # 检查是否使用旧扩展(废弃) if "extensions" in mat: if "KHR_techniques_webgl" in mat["extensions"]: uses_deprecated_ext = True print(" ❌ Uses deprecated KHR_techniques_webgl") # 总结报告 print("\n=== Summary ===") if has_pbr and has_base_color_texture: print("✅ This model has VALID PBR material with texture.") elif has_pbr: print("🟡 This model has PBR but NO TEXTURE (might look gray).") elif uses_deprecated_ext: print("❌ Uses deprecated rendering techniques → likely no color in modern Cesium.") else: print("⚠️ No PBR material defined → may not render correctly in Cesium ≥1.100.") return { "has_pbr": has_pbr, "has_base_color_texture": has_base_color_texture, "uses_deprecated_ext": uses_deprecated_ext, "materials_count": len(materials), "glb_version": version } # 使用示例 if __name__ == "__main__": if len(sys.argv) < 2: print("Usage: python check_b3dm_pbr.py <path_to_tile.b3dm>") sys.exit(1) result = parse_b3dm_pbr_info(sys.argv[1]) print("\nFinal Result:", result) ``` --- ### ✅ 如何运行该脚本? 1. 安装依赖(仅需标准库): ```bash pip install -U jsonschema # 可选:用于验证 glTF schema ``` 2. 运行: ```bash python check_b3dm_pbr.py ./tiles/0.b3dm ``` 3. 输出示例: ``` B3DM Version: 1, Total Length: 123456 GLB Version: 2 Material 0: BuildingMat ✅ Uses pbrMetallicRoughness 🖼️ Has baseColorTexture (index: 0) === Summary === ✅ This model has VALID PBR material with texture. Final Result: {'has_pbr': True, 'has_base_color_texture': True, ...} ``` --- ## ✅ 方法二:使用在线工具快速验证 如果你不想写代码,可以使用以下工具: ### 1. [glTF Validator](https://github.khronos.org/glTF-Validator/) - 上传 `.glb` 文件(需先从 `.b3dm` 中提取) - 查看是否提示 `pbrMetallicRoughness` 缺失 - 检查是否有错误如:`MATERIAL_WITHOUT_PBR_METALLIC_ROUGHNESS` ### 2. [glTF Viewer](https://gltf-viewer.donmccurdy.com/) - 拖入 `.glb`,看是否显示颜色 - 如果是灰色 → 很可能缺少 PBR 定义 > ⚠️ 注意:你必须先把 `.b3dm` 中的 `.glb` 提取出来才能用这些工具。 --- ## ✅ 方法三:自动化批量检测多个 .b3dm 文件 ```python import os def scan_directory_for_b3dm(directory): for root, _, files in os.walk(directory): for f in files: if f.endswith(".b3dm"): path = os.path.join(root, f) print(f"\n🔍 Scanning: {path}") try: res = parse_b3dm_pbr_info(path) if not res["has_pbr"]: print(f"❗ WARNING: {path} lacks PBR materials!") except Exception as e: print(f"❌ Error reading {path}: {e}") # 调用 # scan_directory_for_b3dm("./tileset/") ``` --- ### ✅ 补充建议 | 问题 | 建议 | |------|------| | `.b3dm` 没有纹理但低版 Cesium 显示有色 | 极可能是 Phong 兼容模式生效 | | 高版本 Cesium 显示灰色 | 缺少 `pbrMetallicRoughness.baseColorTexture` | | 模型完全黑色 | 可能光照太弱或纹理路径错误 | | 批量转换失败 | 使用 [Cesium ion API](https://cesium.com/docs/tutorials/importing-assets/) 自动上传和转换 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值