games101作业3

news2024/11/29 1:43:29

作业要求

  • 修改函数 rasterize_triangle(const Triangle& t) in rasterizer.cpp: 在此
    处实现与作业 2 类似的插值算法,实现法向量、颜色、纹理颜色的插值。
  • 修改函数 get_projection_matrix() in main.cpp: 将你自己在之前的实验中
    实现的投影矩阵填到此处,此时你可以运行 ./Rasterizer output.png normal
    来观察法向量实现结果。
  • 修改函数 phong_fragment_shader() in main.cpp: 实现 Blinn-Phong 模型计
    算 Fragment Color.
  • 修改函数 texture_fragment_shader() in main.cpp: 在实现 Blinn-Phong
    的基础上,将纹理颜色视为公式中的 kd,实现 Texture Shading Fragment
    Shader.
  • 修改函数 bump_fragment_shader() in main.cpp: 在实现 Blinn-Phong 的
    基础上,仔细阅读该函数中的注释,实现 Bump mapping.
  • 修改函数 displacement_fragment_shader() in main.cpp: 在实现 Bump
    mapping 的基础上,实现 displacement mapping.

具体实现

  • rasterize_triangle()函数,关键是要知道interpolated_color 、interpolated_normal、interpolated_texcoords、interpolated_shadingcoords这几个参数是根据interpolate()函数计算得出的。
//Screen space rasterization
void rst::rasterizer::rasterize_triangle(const Triangle& t, const std::array<Eigen::Vector3f, 3>& view_pos) 
{
    // TODO: From your HW3, get the triangle rasterization code.
    // TODO: Inside your rasterization loop:
    //    * v[i].w() is the vertex view space depth value z.
    //    * Z is interpolated view space depth for the current pixel
    //    * zp is depth between zNear and zFar, used for z-buffer

    // float Z = 1.0 / (alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());
    // float zp = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
    // zp *= Z;

    // TODO: Interpolate the attributes:
    // auto interpolated_color
    // auto interpolated_normal
    // auto interpolated_texcoords
    // auto interpolated_shadingcoords

    // Use: fragment_shader_payload payload( interpolated_color, interpolated_normal.normalized(), interpolated_texcoords, texture ? &*texture : nullptr);
    // Use: payload.view_pos = interpolated_shadingcoords;
    // Use: Instead of passing the triangle's color directly to the frame buffer, pass the color to the shaders first to get the final color;
    // Use: auto pixel_color = fragment_shader(payload);

    auto v = t.toVector4();

    int xmin = std::min(std::min(v[0].x(), v[1].x()), v[2].x());
    int ymin = std::min(std::min(v[0].y(), v[1].y()), v[2].y());
    int xmax = std::max(std::max(v[0].x(), v[1].x()), v[2].x());
    int ymax = std::max(std::max(v[0].y(), v[1].y()), v[2].y());

    for(int i=xmin;i<=xmax;i++)
    {
        for(int j=ymin;j<=ymax;j++)
        {
            if(insideTriangle(i,j,t.v)){  //点在三角形内部
                auto[alpha, beta, gamma] = computeBarycentric2D(i, j, t.v);
                float Z = 1.0 / (alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());
                float zp = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
                zp *= Z;

                if(zp < depth_buf[get_index(i,j)]){
                    depth_buf[get_index(i,j)] = zp;
                    auto interpolated_color = interpolate(alpha,beta,gamma,t.color[0],t.color[1],t.color[2],1);
                    auto interpolated_normal = interpolate(alpha,beta,gamma,t.normal[0],t.normal[1],t.normal[2],1);
                    auto interpolated_texcoords = interpolate(alpha,beta,gamma,t.tex_coords[0],t.tex_coords[1],t.tex_coords[2],1);
                    auto interpolated_shadingcoords = interpolate(alpha,beta,gamma,view_pos[0],view_pos[1],view_pos[2],1);
                    fragment_shader_payload payload(interpolated_color, interpolated_normal.normalized(), interpolated_texcoords, texture ? &*texture : nullptr);
                    payload.view_pos = interpolated_shadingcoords;
                    auto pixel_color = fragment_shader(payload);
                    Vector2i p(i,j);
                    set_pixel(p,pixel_color);
                }
            }
        }
    }
}
  • get_projection_matrix()函数直接把作业1中的代码搬过来
Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio, float zNear, float zFar)
{
   // Students will implement this function

    Eigen::Matrix4f projection = Eigen::Matrix4f::Identity();

    // TODO: Implement this function
    // Create the projection matrix for the given parameters.
    // Then return it.

    //创建透视变正交矩阵
    Eigen::Matrix4f m = Eigen::Matrix4f::Identity();;
    m << zNear,0,0,0,
        0,zNear,0,0,
        0,0,zNear+zFar,-zNear*zFar,
        0,0,1,0;
    
    //创建正交投影矩阵
    Eigen::Matrix4f q1 = Eigen::Matrix4f::Identity(),q2 = Eigen::Matrix4f::Identity();

    float top = tan(eye_fov/2/180*acos(-1)) * -zNear;
    float bottom = -top;
    float right = top * aspect_ratio;
    float left = -right;
    //缩放
    q1 << 2.0/(right - left),0,0,0,
        0,2.0/(top - bottom),0,0,
        0,0,2.0/(zNear - zFar),0,
        0,0,0,1;

    //平移
    q2 << 1,0,0,-(right+left)/2.0,
        0,1,0,-(top+bottom)/2.0,
        0,0,1,-(zNear+zFar)/2.0,
        0,0,0,1;

    projection = q1 * q2 * m;

    return projection;
}
  • phong_fragment_shader()函数,在这之前你需要知道Blinn-Phong反射模型的计算公式:参考博客在这里插入图片描述
    下面解释一下该函数中的一些参数,知道这些参数的意义之后再去做会清晰很多:amb_light_intensity代表环境光的强度,对应公式中的Ia;
    lights表示两个光源,它的强度对应公式中的 I(不是向量l);
    eye_pos代表眼睛的位置;
    color、point、normal表示着色点的颜色、位置、法向量;
    用光源的位置减去着色点的位置point,然后标准化一下就得到了向量l;
    用眼睛的位置减去着色点的位置标准化一下得到向量v;
    (v+l)/2就得到了向量h
Eigen::Vector3f phong_fragment_shader(const fragment_shader_payload& payload)
{
    Eigen::Vector3f ka = Eigen::Vector3f(0.005, 0.005, 0.005);
    Eigen::Vector3f kd = payload.color;
    Eigen::Vector3f ks = Eigen::Vector3f(0.7937, 0.7937, 0.7937);

    auto l1 = light{{20, 20, 20}, {500, 500, 500}};  //光源位置,强度
    auto l2 = light{{-20, 20, 0}, {500, 500, 500}};

    std::vector<light> lights = {l1, l2};
    Eigen::Vector3f amb_light_intensity{10, 10, 10};  //环境光
    Eigen::Vector3f eye_pos{0, 0, 10};

    float p = 150;

    //着色点的信息
    Eigen::Vector3f color = payload.color;
    Eigen::Vector3f point = payload.view_pos;
    Eigen::Vector3f normal = payload.normal;

    Eigen::Vector3f result_color = {0, 0, 0};
    for (auto& light : lights)
    {
        // TODO: For each light source in the code, calculate what the *ambient*, *diffuse*, and *specular* 
        // components are. Then, accumulate that result on the *result_color* object.
        Eigen::Vector3f ambient = ka.cwiseProduct(amb_light_intensity);

        //距离r的平方
        float r = (light.position - point).dot(light.position - point);

        Eigen::Vector3f l = (light.position - point).normalized();
        Eigen::Vector3f v = (eye_pos - point).normalized();
        Eigen::Vector3f h = (l + v).normalized();

        double c = normal.normalized().dot(l);
        Eigen::Vector3f diffuse = kd.cwiseProduct(light.intensity/r) * std::max(0.0,c);

        c = normal.normalized().dot(h);
        Eigen::Vector3f specular = ks.cwiseProduct(light.intensity/r) * pow(std::max(0.0,c),p);


        result_color = result_color + ambient + diffuse + specular;
    }

    return result_color * 255.f;
}

运行之后你会得到这样的结果

在这里插入图片描述

  • texture_fragment_shader()相对来说就比较好实现了
Eigen::Vector3f texture_fragment_shader(const fragment_shader_payload& payload)
{
    Eigen::Vector3f return_color = {0, 0, 0};
    if (payload.texture)
    {
        // TODO: Get the texture value at the texture coordinates of the current fragment
        Eigen::Vector3f color = payload.texture->getColor(payload.tex_coords.x(),payload.tex_coords.y());
        return_color += color;
        //std::cout<<color;

    }
    Eigen::Vector3f texture_color;
    texture_color << return_color.x(), return_color.y(), return_color.z();

    Eigen::Vector3f ka = Eigen::Vector3f(0.005, 0.005, 0.005);
    Eigen::Vector3f kd = texture_color / 255.f;
    Eigen::Vector3f ks = Eigen::Vector3f(0.7937, 0.7937, 0.7937);

    auto l1 = light{{20, 20, 20}, {500, 500, 500}};  
    auto l2 = light{{-20, 20, 0}, {500, 500, 500}};

    std::vector<light> lights = {l1, l2};
    Eigen::Vector3f amb_light_intensity{10, 10, 10};
    Eigen::Vector3f eye_pos{0, 0, 10};

    float p = 150;

    Eigen::Vector3f color = texture_color;
    Eigen::Vector3f point = payload.view_pos;
    Eigen::Vector3f normal = payload.normal;

    Eigen::Vector3f result_color = {0, 0, 0};

    for (auto& light : lights)
    {
        // TODO: For each light source in the code, calculate what the *ambient*, *diffuse*, and *specular* 
        // components are. Then, accumulate that result on the *result_color* object.
        Eigen::Vector3f ambient = ka.cwiseProduct(amb_light_intensity);

        //距离r的平方
        float r = (light.position - point).dot(light.position - point);

        Eigen::Vector3f l = (light.position - point).normalized();
        Eigen::Vector3f v = (eye_pos - point).normalized();
        Eigen::Vector3f h = (l + v).normalized();

        double c = normal.normalized().dot(l);
        Eigen::Vector3f diffuse = kd.cwiseProduct(light.intensity/r) * std::max(0.0,c);

        c = normal.normalized().dot(h);
        Eigen::Vector3f specular = ks.cwiseProduct(light.intensity/r) * pow(std::max(0.0,c),p);


        result_color = result_color + ambient + diffuse + specular;

    }

    return result_color * 255.f;
}

结果如下

在这里插入图片描述
后两个函数emmmm不太懂,代码如下

Eigen::Vector3f displacement_fragment_shader(const fragment_shader_payload& payload)
{
    
    Eigen::Vector3f ka = Eigen::Vector3f(0.005, 0.005, 0.005);
    Eigen::Vector3f kd = payload.color;
    Eigen::Vector3f ks = Eigen::Vector3f(0.7937, 0.7937, 0.7937);

    auto l1 = light{{20, 20, 20}, {500, 500, 500}};
    auto l2 = light{{-20, 20, 0}, {500, 500, 500}};

    std::vector<light> lights = {l1, l2};
    Eigen::Vector3f amb_light_intensity{10, 10, 10};
    Eigen::Vector3f eye_pos{0, 0, 10};

    float p = 150;

    Eigen::Vector3f color = payload.color; 
    Eigen::Vector3f point = payload.view_pos;
    Eigen::Vector3f normal = payload.normal;

    float kh = 0.2, kn = 0.1;
    
    // TODO: Implement displacement mapping here
    // Let n = normal = (x, y, z)
    // Vector t = (x*y/sqrt(x*x+z*z),sqrt(x*x+z*z),z*y/sqrt(x*x+z*z))
    // Vector b = n cross product t
    // Matrix TBN = [t b n]
    // dU = kh * kn * (h(u+1/w,v)-h(u,v))
    // dV = kh * kn * (h(u,v+1/h)-h(u,v))
    // Vector ln = (-dU, -dV, 1)
    // Position p = p + kn * n * h(u,v)
    // Normal n = normalize(TBN * ln)

    float x = normal.x();
    float y = normal.y();
    float z = normal.z();

    Eigen::Vector3f t = Eigen::Vector3f(x * y / std::sqrt(x * x + z * z), std::sqrt(x * x + z * z), z * y / std::sqrt(x * x + z * z));
    Eigen::Vector3f b = normal.cross(t);

    Eigen::Matrix3f TBN;
    TBN <<
        t.x(), b.x(), normal.x(),
        t.y(), b.y(), normal.y(),
        t.z(), b.z(), normal.z();

    float u = payload.tex_coords.x();
    float v = payload.tex_coords.y();
    float w = payload.texture->width;
    float h = payload.texture->height;

    float dU = kh * kn * (payload.texture->getColor(u + 1.0f / w, v).norm() - payload.texture->getColor(u, v).norm());
    float dV = kh * kn * (payload.texture->getColor(u, v + 1.0f / h).norm() - payload.texture->getColor(u, v).norm());

    Eigen::Vector3f ln = Eigen::Vector3f(-dU, -dV, 1.0f);

    point += (kn * normal * payload.texture->getColor(u, v).norm());

    normal = (TBN * ln).normalized();

    Eigen::Vector3f result_color = {0, 0, 0};

    for (auto& light : lights)
    {
        // TODO: For each light source in the code, calculate what the *ambient*, *diffuse*, and *specular* 
        // components are. Then, accumulate that result on the *result_color* object.

        Eigen::Vector3f light_dir = (light.position - point).normalized();
        Eigen::Vector3f view_dir = (eye_pos - point).normalized();
        Eigen::Vector3f half_vector = (light_dir + view_dir).normalized();

        // 距离衰减
        float r2 = (light.position - point).dot(light.position - point);

        //环境光
        //cwiseProduct():矩阵点对点相乘
        Eigen::Vector3f La = ka.cwiseProduct(amb_light_intensity);

        //漫反射
        Eigen::Vector3f Ld = kd.cwiseProduct(light.intensity / r2);
        Ld *= std::max(0.0f, normal.normalized().dot(light_dir));

        //高光
        Eigen::Vector3f Ls = ks.cwiseProduct(light.intensity / r2);
        Ls *= std::pow(std::max(0.0f, normal.normalized().dot(half_vector)), p);

        result_color += (La + Ld + Ls);
    }

    return result_color * 255.f;
}


Eigen::Vector3f bump_fragment_shader(const fragment_shader_payload& payload)
{
    
    Eigen::Vector3f ka = Eigen::Vector3f(0.005, 0.005, 0.005);
    Eigen::Vector3f kd = payload.color;
    Eigen::Vector3f ks = Eigen::Vector3f(0.7937, 0.7937, 0.7937);

    auto l1 = light{{20, 20, 20}, {500, 500, 500}};
    auto l2 = light{{-20, 20, 0}, {500, 500, 500}};

    std::vector<light> lights = {l1, l2};
    Eigen::Vector3f amb_light_intensity{10, 10, 10};
    Eigen::Vector3f eye_pos{0, 0, 10};

    float p = 150;

    Eigen::Vector3f color = payload.color; 
    Eigen::Vector3f point = payload.view_pos;
    Eigen::Vector3f normal = payload.normal;


    float kh = 0.2, kn = 0.1;

    // TODO: Implement bump mapping here
    // Let n = normal = (x, y, z)
    // Vector t = (x*y/sqrt(x*x+z*z),sqrt(x*x+z*z),z*y/sqrt(x*x+z*z))
    // Vector b = n cross product t
    // Matrix TBN = [t b n]
    // dU = kh * kn * (h(u+1/w,v)-h(u,v))
    // dV = kh * kn * (h(u,v+1/h)-h(u,v))
    // Vector ln = (-dU, -dV, 1)
    // Normal n = normalize(TBN * ln)

    float x = normal.x();
    float y = normal.y();
    float z = normal.z();

    Eigen::Vector3f t = Eigen::Vector3f(x * y / std::sqrt(x * x + z * z), std::sqrt(x * x + z * z), z * y / std::sqrt(x * x + z * z));
    Eigen::Vector3f b = normal.cross(t);

    Eigen::Matrix3f TBN;
    TBN << 
        t.x(), b.x(), normal.x(),
        t.y(), b.y(), normal.y(),
        t.z(), b.z(), normal.z();

    float u = payload.tex_coords.x();
    float v = payload.tex_coords.y();
    float w = payload.texture->width;
    float h = payload.texture->height;

    float dU = kh * kn * (payload.texture->getColor(u + 1.0f / w, v).norm() - payload.texture->getColor(u, v).norm());
    float dV = kh * kn * (payload.texture->getColor(u, v + 1.0f / h).norm() - payload.texture->getColor(u, v).norm());

    Eigen::Vector3f ln = Eigen::Vector3f(-dU, -dV, 1.0f);
    normal = TBN * ln;

    Eigen::Vector3f result_color = {0, 0, 0};
    result_color = normal.normalized();

    return result_color * 255.f;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/550528.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JUC基础】08. 三大工具类

1、前言 JUC包中包含了三个非常实用的工具类&#xff1a;CountDownLatch&#xff08;倒计数器&#xff09;&#xff0c;CyclicBarrier&#xff08;循环栅栏&#xff09;&#xff0c;Semaphore&#xff08;信号量&#xff09;。 2、倒计数器&#xff1a;CountDownLatch 2.1、…

基于Java+SpringBoot+Vue前后端分离机票预定/订购系统设计与实现(视频讲解)

博主介绍&#xff1a;✌全网粉丝3W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

章节2 Matplotlib 绘图基础

目录 课时 2 Matplotlib简介及绘制简单线型图 课时 3 图例和标题 课时 4 自定义图形样式 课时 4 绘制条形图 课时 2 Matplotlib简介及绘制简单线型图 线的画法 plt.plot&#xff0c;同时提供x轴坐标和y轴坐标 课时 3 图例和标题 x 轴数据默认即可&#xff0c;如下所示 x轴代…

SimpleDateFormat非线程安全问题

文章目录 1. SimpleDateFormat介绍2. 测试SimpleDateFormat的非线程安全性3. 解决方案一4. 解决方案二 1. SimpleDateFormat介绍 SimpleDateFormat是Java中的一个类&#xff0c;用于将日期对象格式化为特定的字符串表示形式&#xff0c;或者将特定格式的字符串解析为日期对象。…

netstat 连接通信的信息和状态、以及ss

netstat 常用参数 t 只显示tcpu只显示udpnnum 数字形式显示地址和端口号l listen 显示监听端口 pprogram 显示进程aall 所有连接和监听r显示路由表 netstat -lnp 显示服务监听端口tcpudpsocket &#xff0c;socket 文件也用来同一台服务器的进程之间通信的…

Spring中的MergedBeanDefinitionPostProcessor有什么作用 ?

Spring中的MergedBeanDefinitionPostProcessor有什么作用 ? 引言调用时机加载bean定义的几种方式postProcessMergedBeanDefinition接口作用小结 引言 MergedBeanDefinitionPostProcessor这个Bean后置处理器大家可能关注的比较少,其本身也只提供了一个bean生命周期回调接口: …

iptable 防火墙一

目录 iptables概述netfilter/iptables 关系四表五链四表&#xff1a;五链&#xff1a; 规则链之间的匹配顺序主机型防火墙&#xff1a;规则链内的匹配顺序&#xff1a; iptables 安装iptables防火墙的配置方法&#xff1a;iptables 命令行配置方法&#xff1a;常用的控制类型&a…

一文读懂大语言模型

以ChatGPT为代表的大语言模型被很多人认为是新一轮科技革命的起点&#xff0c;本文旨在通过概念性介绍&#xff0c;让普通人能够尽可能理解人工智能以及大语言模型的基本概念&#xff0c;从而了解这些技术能做以及不能做什么。原文: A Very Gentle Introduction to Large Langu…

v4l2数据结构分析

v4l2数据结构分析 文章目录 v4l2数据结构分析Video4Linux2设备v4l2_device媒体设备media_deviceVideo4Linux2子设备v4l2_subdevVideo4Linux2子设备的操作集v4l2_subdev_opsVideo4Linux2子设备的内部操作集v4l2_subdev_internal_opsVideo4Linux2控制处理器v4l2_ctrl_handlerVide…

微信自动聊天机器狗,配置chatGPT,比Siri还智能!

大家好&#xff0c;我是TheWeiJun&#xff1b;最近看见微信里各个群聊都在聊chatGPT&#xff0c;甚至有的大佬们都把chatGPT接入了微信群聊&#xff0c;于是就有粉丝来找小编&#xff0c;希望能出一期chatGPT的文章&#xff1b;故今天这篇文章我将手把手教大家如何实现并自定义…

学习《信息系统项目管理师教程》第4版应关注的PMBOK的巨大变化

学习《信息系统项目管理师教程》第4版应关注的PMBOK的巨大变化 《信息系统项目管理师教程》的第4版比起第3版来有不少变化。但是&#xff0c;这种变化完全没有体现出PMBOK第7版带来的巨大变化。 因为&#xff0c;在从《信息系统项目管理师教程》第3版出版的2017年到现在&…

uvc驱动中的v4l2

uvc驱动中的v4l2 文章目录 uvc驱动中的v4l2v4l2_device_registervideo_register_devicev4l2_ioctlsvideo_usercopy v4l2_device_register /driver/media/v4l2-core/v4l2-device.c uvc_probe->v4l2_device_register v4l2_device_register 只是用于初始化一些东西&#xff0c…

【数项级数】无穷个数相加一定是个数吗?

数项级数 引入思考问题转化 定义总结重要的例子练习题 引入 思考 数项级数&#xff0c;其实就是要解决无穷个数相加的问题。 而对于无穷求和的问题&#xff0c;思考&#xff1a;无穷个数相加一定是个数吗&#xff1f; 下面&#xff0c;我们来举几个例子&#xff1a; 1 2 2 …

创世纪:比特币诞生记

比特币的诞生 1. 创始区块2. 第一个举手的人3. 比特币的疯狂 1. 创始区块 2008年10月31日纽约时间下午2点10分&#xff0c;自称中本聪的人向一个邮件列表&#xff0c;包括密码学专家和爱好者几百个成员&#xff0c;发送了一封电子邮件。“我一直在研究一个新的电子现金系统&am…

springboot旅游资源管理系统门票酒店预订系统_b0a6b

Spring Boot 是 Spring 家族中的一个全新的框架&#xff0c;它用来简化Spring应用程序的创建和开发过程。也可以说 Spring Boot 能简化我们之前采用SSM&#xff08;Spring MVC Spring MyBatis &#xff09;框架进行开发的过程。config&#xff1a;主要用来存储配置文件&#…

chatgpt赋能Python-pythoncontinue怎么用

Python continue语句&#xff1a;提高代码效率的绝佳工具 什么是Python continue语句&#xff1f; Python的continue语句可以使循环跳过当前的迭代。这意味着如果在循环内部存在满足某特定条件的语句&#xff0c;那么我们就可以使用continue语句跳过当前循环。Python中的cont…

【Nodejs】使用Nodejs搭建HTTP服务,并实现公网远程访问

文章目录 前言1.安装Node.js环境2.创建node.js服务3. 访问node.js 服务4.内网穿透4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5.固定公网地址 转载自内网穿透工具的文章&#xff1a;使用Nodejs搭建HTTP服务&#xff0c;并实现公网远程访问「内网穿透」 前言 Node.js…

Mybatis Plus实现乐观锁

文章目录 1 概念2 实现思路3 实现步骤步骤1:数据库表添加列步骤2:在模型类中添加对应的属性步骤3:添加乐观锁的拦截器步骤4:执行更新操作 1 概念 在讲解乐观锁之前&#xff0c;我们还是先来分析下问题: 业务并发现象带来的问题 : 秒杀 假如有100个商品或者票在出售&#xff…

【数据分享】我国各县1992—2019年社会经济指标(7个指标\无需转发)

社会经济指标常用于各项研究中&#xff0c;之前基于《中国城市统计年鉴》我们整理了1999-2020年地级市的地区生产总值及一二三产构成数据&#xff08;可查看之前的文章获悉详情&#xff09;&#xff01; 我们发现在学者Chen Yahan在Figshare 数据库中提供了1992—2019年以县为…

动态规划-状态压缩DP

[SCOI2005] 互不侵犯 题目描述 https://www.luogu.com.cn/problem/P1896 在NN的棋盘里面放K个国王&#xff0c;使他们互不攻击&#xff0c;共有多少种摆放方案。国王能攻击到它上下左右&#xff0c;以及左上左下右上右下八个方向上附近的各一个格子&#xff0c;共8个格子。 …