zoukankan      html  css  js  c++  java
  • 【学习】006数据交换格式与SpringIOC底层实现

    课程目标

    XML和JSON

     Java反射机制

    手写SpringIOC

    什么是数据交换格式

    客户端与服务器常用数据交换格式xml、json、html

    数据交换格式用场景

    移动端(安卓、IOS)通讯方式采用http协议+JSON格式 走restful风格。

    很多互联网项目都采用Http协议+JSON

    因为xml比较重WebService服务采用http+xml格式 银行项目使用比较多

    数据交换格式

    JSON简单使用

    什么是JSON

    JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,相比于xml这种数据交换格式来说,因为解析xml比较的复杂,而且需要编写大段的代码,所以客户端和服务器的数据交换格式往往通过JSON来进行交换。

    样例:

    {
        "id": "10",
        "name": " 洪墨水",
        "items": [
            {
                "itemId": "20",
                "itemName": "JSON"
            },
            {
                "itemId": "21",
                "itemName": "XML"
            }
        ]
    }

    JSONJavaScript 对象表示法(JavaScript Object Notation)。

    JSON的形式是用大括号“{}”包围起来的项目列表,每一个项目间用逗号(,)分隔,而项目就是用冒号(:)分隔的属性名和属性值。这是典型的字典表示形式,也再次表明javascript里的对象就是字典结构。不管多么复杂的对象,都可以用一句JSON代码来创建并赋值。在JSON中,名称 / 值对包括字段名称(在双引号中),后面写一个冒号,然后是值。

    SON格式的分类

    JSON有两种结构

    json简单说就是javascript中的对象和数组,所以这两种结构就是对象和数组两种结构,通过这两种结构可以表示各种复杂的结构

    1、对象:对象在js中表示为“{}”括起来的内容,数据结构为 {keyvalue,keyvalue,...}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理解,取值方法为对象.key 获取属性值,这个属性值的类型可以是数字、字符串、数组、对象几种。

    2、数组:数组在js中是中括号“[]”括起来的内容,数据结构为 ["java","javascript","vb",...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是数字、字符串、数组、对象几种。
    经过对象、数组2种结构就可以组合成复杂的数据结构了。

    常用JSON解析框架

    fastjson(阿里)、gson(谷歌)、jackson(SpringMVC自带)

    使用fastjson解析json

    添加jar fastjson-1.1.43 或引入maven依赖

    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.1.43</version>
    </dependency>

    使用fastjson api

       // 把JSON文本parse为JSONObject或者JSONArray
        public static final Object parse(String text);
    
        // 把JSON文本parse成JSONObject
        public static final JSONObject parseObject(String text);
    
        // 把JSON文本parse为JavaBean
        public static final <T> T parseObject(String text, Class<T> clazz);
    
        // 把JSON文本parse成JSONArray
        public static final JSONArray parseArray(String text);
    
        // 把JSON文本parse成JavaBean集合
        public static final <T> List<T> parseArray(String text, Class<T> clazz);
    
        // 将JavaBean序列化为JSON文本
        public static final String toJSONString(Object object);
    
        // 将JavaBean序列化为带格式的JSON文本
        public static final String toJSONString(Object object, boolean prettyFormat);
    
        // 将JavaBean转换为JSONObject或者JSONArray
        public static final Object toJSON(Object javaObject);

    解析json

    static String jsonStr = "{"id": "10","name": " 洪墨水","items": [{"itemId": "20","itemName": "JSON"},{"itemId": "21","itemName": "XML"}]}";
    
        public static void main(String[] args)
        {
            JSONObject jsonObject = new JSONObject();
            // 将json字符串转为jsonObject
            JSONObject jsonStrObject = jsonObject.parseObject(jsonStr);
            JSONArray jsonArray = jsonStrObject.getJSONArray("items");
            for (Object object : jsonArray)
            {
                JSONObject stObject = (JSONObject) object;
                String itemId = stObject.getString("itemId");
                String itemName = stObject.getString("itemName");
                System.out.println(itemId + ":" + itemName);
            }
        }

    Json转对象

    定义类

    package com.hongmoshui.entity;
    
    public class Item
    {
        private String itemId;
    
        private String itemName;
    
        public String getItemId()
        {
    
            return itemId;
        }
    
        public void setItemId(String itemId)
        {
    
            this.itemId = itemId;
        }
    
        public String getItemName()
        {
    
            return itemName;
        }
    
        public void setItemName(String itemName)
        {
    
            this.itemName = itemName;
        }
    
        @Override
        public String toString()
        {
            return "Item [itemId=" + itemId + ", itemName=" + itemName + "]";
        }
    
    }
    package com.hongmoshui.entity;
    
    import java.util.List;
    
    public class User extends Object
    {
    
        private String id;
    
        private String name;
    
        private List<Item> items;
    
        public User(String id)
        {
            System.out.println("我是通过有参构造函数初始化 id:" + id);
            this.id = id;
        }
    
        public User()
        {
            System.out.println("我是无参数构造函数初始化");
        }
    
        public String getId()
        {
    
            return id;
        }
    
        public void setId(String id)
        {
    
            this.id = id;
        }
    
        public String getName()
        {
    
            return name;
        }
    
        public void setName(String name)
        {
    
            this.name = name;
        }
    
        public List<Item> getItems()
        {
    
            return items;
        }
    
        public void setItems(List<Item> items)
        {
    
            this.items = items;
        }
    
        @Override
        public String toString()
        {
            return "User [id=" + id + ", name=" + name + ", items=" + items + "]";
        }
    
    }

    Json转换对象api

            // 2.使用java反射机制 对应生成对象
            User user = new JSONObject().parseObject(json, User.class);
            System.out.println("user:" + user.toString());

    组装json

    Json api封装json

            // 1.json api 封装json
            JSONObject root = new JSONObject();
            root.put("id", "01");
            root.put("name", "张三");
            JSONArray arrayList = new JSONArray();
            JSONObject object1 = new JSONObject();
            object1.put("itemId", "20");
            object1.put("itemName", "JSON");
            JSONObject object2 = new JSONObject();
            object2.put("itemId", "30");
            object2.put("itemName", "Object");
            arrayList.add(object1);
            arrayList.add(object2);
            root.put("items", arrayList);
            System.out.println(root.toJSONString());        

    将对象转换成json字符串

         User user = new User();
            user.setId("01");
            user.setName("张三");
            List<Item> items = new ArrayList<Item>();
            Item item1 = new Item();
            item1.setItemId("20");
            item1.setItemName("JSON");
            Item item2 = new Item();
            item2.setItemId("30");
            item2.setItemName("Object");
            items.add(item1);
            items.add(item2);
            user.setItems(items);
            System.out.println(new JSONObject().toJSONString(user));

    XML简单使用

    什么是XML?

    它是可扩展标记语言(Extensible Markup Language,简称XML),是一种标记语言。

    XML 全称为可扩展的标记语言。主要用于描述数据和用作配置文件。

    XML 文档在逻辑上主要由一下 5 个部分组成:

    XML 声明:指明所用 XML 的版本、文档的编码、文档的独立性信息

    文档类型声明:指出 XML 文档所用的 DTD

    元素:由开始标签、元素内容和结束标签构成

    注释:以结束,用于对文档中的内容起一个说明作用

    处理指令:通过处理指令来通知其他应用程序来处理非 XML 格式的数据,格式为

      XML 文档的根元素被称为文档元素,它和在其外部出现的处理指令、注释等作为文档实体的子节点,根元素本身和其内部的子元素也是一棵树。

     XML样例

    <?xml version="1.0" encoding="UTF-8"?>
    <students>
        <student1 id="001">
            <微信公众号>洪墨水001</微信公众号>
            <学号>20140101</学号>
            <地址>广东省深圳</地址>
            <座右铭>要么强大,要么听话</座右铭>
        </student1>
        <student2 id="002">
            <新浪微博>洪墨水002</新浪微博>
            <学号>20140102</学号>
            <地址>广东省广州</地址>
            <座右铭>在哭泣中学会坚强</座右铭>
        </student2>
    </students> 

    <?xml version="1.0" encoding="UTF-8"?>作用:xml文件头部要写的话,说明了xml的版本和编码,utf-8一般是网络传输用的编码

    XML解析方式?

    Dom4j、Sax、Pull

    Dom4j与Sax区别

     dom4j不适合大文件的解析,因为它是一下子将文件加载到内存中,所以有可能出现内存溢出,sax是基于事件来对xml进行解析的,所以他可以解析大文件的xml,也正是因为如此,所以dom4j可以对xml进行灵活的增删改查和导航,而sax没有这么强的灵活性,所以sax经常是用来解析大型xml文件,而要对xml文件进行一些灵活(crud)操作就用dom4j。

    使用dom4j解析xml

    解析XML过程是通过获取Document对象,然后继续获取各个节点以及属性等操作,因此获取Document对象是第一步,大体说来,有三种方式:

    1.自己创建Document对象

    Document document = DocumentHelper.createDocument();
    Element root = document.addElement("students");

    其中students是根节点,可以继续添加其他节点等操作。

    2.读取XML文本内容获取Document对象

    // 创建SAXReader对象
    SAXReader reader = new SAXReader();
    // 读取文件 转换成Document
    Document document = reader.read(new File("XXXX.xml"));

    3.String类型的内容转换成Document对象

    String xmlStr = "<students>......</students>";
    Document document = DocumentHelper.parseText(xmlStr);

    解析xml代码

    Xml配置:

    <?xml version="1.0" encoding="UTF-8"?>
    <students>
        <student1 id="001">
            <微信公众号>洪墨水001</微信公众号>
            <学号>20140101</学号>
            <地址>广东省深圳</地址>
            <座右铭>要么强大,要么听话</座右铭>
        </student1>
        <student2 id="002">
            <新浪微博>洪墨水002</新浪微博>
            <学号>20140102</学号>
            <地址>广东省广州</地址>
            <座右铭>在哭泣中学会坚强</座右铭>
        </student2>
    </students> 

    Java代码:

    package com.hongmoshui;
    
    import java.io.File;
    import java.util.Iterator;
    import java.util.List;
    
    import org.dom4j.Attribute;
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    
    public class Text
    {
        public static void main(String[] args) throws DocumentException
        {
            SAXReader saxReader = new SAXReader();
            Document read = saxReader.read(new File(ClassLoader.getSystemResource("stu.xml").getPath()));
            // 获取根节点
            Element rootElement = read.getRootElement();
            getNodes(rootElement);
    
        }
    
        /**
         * 读取节点信息
         * @param rootElement 根节点
         * @author 墨水
         */
        static public void getNodes(Element rootElement)
        {
            System.out.println("当前节点名称:" + rootElement.getName());
            // 获取属性ID
            List<Attribute> attributes = rootElement.attributes();
            for (Attribute attribute : attributes)
            {
                System.out.println("属性:" + attribute.getName() + "---" + attribute.getText());
            }
            if (!rootElement.getTextTrim().equals(""))
            {
                System.out.println(rootElement.getName() + "--" + rootElement.getText());
            }
            // 使用迭代器遍历
            Iterator<Element> elementIterator = rootElement.elementIterator();
            while (elementIterator.hasNext())
            {
                Element next = elementIterator.next();
                getNodes(next);
            }
    
        }
    
    }

    注意:

     ClassLoader().getSystemResource("stu.xml").getPath() 获取当前项目路径中的stu.xml文件的路径

    XML与JSON区别

    Xml是重量级数据交换格式,占宽带比较大。

    JSON是轻量级交换格式,xml占宽带小。

    所有很多互联网公司都会使用json作为数据交换格式

    很多银行项目,大多数还是在使用xml。

    Java反射机制

    什么是Java反射

    就是正在运行,动态获取这个类的所有信息。

    反射机制的作用

      1,反编译:.class-->.java

       2.通过反射机制访问java对象的属性,方法,构造方法等;

    反射机制的应用场景

    Jdbc 加载驱动-----

    Spring ioc

    框架

    反射机制获取类有三种方法

            // 第一种方式:
            Class c1 = Class.forName("User");
    
            // 第二种方式:java中每个类型都有class 属性.
            Class c2 = User.class;
    
            // 第三种方式: java语言中任何一个java对象都有getClass方法
            User user = new User();
    
            // c3是运行时类(e的运行时类是User)
            Class c3 = user.getClass();

    反射创建对象的方式

            // 创建此Class 对象所表示的类的一个新实例
            Class<?> forName = Class.forName("com.hongmoshui.entity.User");
            // 调用了User的无参数构造方法.
            Object objectInstance = forName.newInstance();
            System.out.println(objectInstance.toString());
            // 调用了User的有参数构造方法.
            Constructor<?> constructor = forName.getConstructor(String.class);
            User userInstance = (User) constructor.newInstance("123");
            System.out.println(userInstance.toString());

    反射创建api

    方法名称

    作用

    getDeclaredMethods []

    获取该类的所有方法

    getReturnType()

    获取该类的返回值

    getParameterTypes()

    获取传入参数

    getDeclaredFields()

    获取该类的所有字段

    setAccessible

    允许访问私有成员

    使用反射为类私有属性赋值

            // 为user对象私有属性赋值
            Class<?> classUser = Class.forName("com.hongmoshui.entity.User");
            // 获取到当前的所有属性
            Field[] fields = classUser.getDeclaredFields();
            for (Field field : fields)
            {
                System.out.println("属性:" + field.getName());
            }
            // 获取当前所有的方法
            Method[] declaredMethods = classUser.getDeclaredMethods();
            for (Method method : declaredMethods)
            {
                System.out.println("方法:" + method.getName());
            }
            // 初始化对象
            User user = (User) classUser.newInstance();
            Field declaredField = classUser.getDeclaredField("id");
            // 标记为true 允许反射赋值
            declaredField.setAccessible(true);
            System.out.println("使用反射机制给id赋值为:" + user.getId());
            declaredField.set(user, "20");
            System.out.println("user:" + user.toString());

    关于获取类的字段有两种方式:getFields()和getDeclaredFields()。我们先来看看这两者的区别吧:

    getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。 
    getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。

    同样类似的还有getConstructors()和getDeclaredConstructors()、getMethods()和getDeclaredMethods(),这两者分别表示获取某个类的方法、构造函数。

    JDBC反射加载驱动

    maven的jar包依赖

            <!-- MySql -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.47</version>
            </dependency>

    表结构:

    CREATE TABLE `users` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
    `name` varchar(255) DEFAULT NULL COMMENT '名字',
    `age` int(11) DEFAULT NULL COMMENT '年龄',
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

    演示代码:

    package com.hongmoshui;
    
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    import com.mysql.jdbc.Connection;
    import com.mysql.jdbc.PreparedStatement;
    
    public class Text
    {
        public static void main(String[] args) throws Exception
        {
            Connection connection =null;
            PreparedStatement statement = null;
            ResultSet resultSet  =null;
            try
            {
                // 加载驱动类
                Class.forName("com.mysql.jdbc.Driver");
                // 通过DriverManager获取数据库连接
                String url = "jdbc:mysql://localhost:3306/test";
                String user = "root";
                String password = "master";
                connection = (Connection) DriverManager.getConnection(url, user, password);
                // 获取预编译得SQL语句的对象
                statement = (PreparedStatement) connection.prepareStatement("insert into users (name, age) value (?, ?)");
                statement.setString(1, "hongmoshui");
                statement.setInt(2, 21);
                statement.executeUpdate();
    
                resultSet = statement.executeQuery("select * from users");
                // 操作ResultSet结果集
                while (resultSet.next())
                {
                    // 第一种获取字段方式
                    System.out.println(resultSet.getString(1) + " " + resultSet.getString(2) + " " + resultSet.getString(3));
                }
            }
            catch (ClassNotFoundException e)
            {
                e.printStackTrace();
                System.out.println("加载驱动失败");
            }
            catch (SQLException e)
            {
                e.printStackTrace();
            }
            finally
            {
                // 关闭数据库连接
                if (resultSet != null)
                {
                    resultSet.close();
                }
                if (statement != null)
                {
                    statement.close();
                }
                if (connection != null)
                {
                    connection.close();
                }
            }
        }
    }

    禁止使用反射机制初始化

    将构造函数为私有化

    手写SpringIOC框架

    什么是SpringIOC

    什么是SpringIOC,就是把每一个bean(实体类)与bean(实体了)之间的关系交给第三方容器进行管理。

    Xml配置:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="    
         http://www.springframework.org/schema/beans     
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    
         http://www.springframework.org/schema/tx     
         http://www.springframework.org/schema/tx/spring-tx-3.0.xsd    
         http://www.springframework.org/schema/aop     
         http://www.springframework.org/schema/aop/spring-aop-3.0.xsd    
         http://www.springframework.org/schema/context    
         http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
        <bean id="user1" class="com.hongmoshui.service.UserEntity">
            <property name="userId" value="0001"></property>
            <property name="userName" value="红墨水001"></property>
        </bean>
        <bean id="user2" class="com.hongmoshui.service.UserEntity">
            <property name="userId" value="0002"></property>
            <property name="userName" value="红墨水002"></property>
        </bean>
    </beans>  

    Java代码:

    UserEntity:

    package com.hongmoshui.service;
    
    public class UserEntity
    {
        private String userId;
    
        private String userName;
    
        public UserEntity()
        {
            System.out.println("无参构造函数....");
        }
    
        public String getUserId()
        {
    
            return userId;
        }
    
        public void setUserId(String userId)
        {
    
            this.userId = userId;
        }
    
        public String getUserName()
        {
    
            return userName;
        }
    
        public void setUserName(String userName)
        {
    
            this.userName = userName;
        }
    
        @Override
        public String toString()
        {
            return "UserEntity [userId=" + userId + ", userName=" + userName + "]";
        }
    }

    main:

         //1.读取springxml配置
            ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext(
                    "applicationContext.xml");
            //2.获取bean对象
            UserEntity userEntity = (UserEntity) classPathXmlApplicationContext.getBean("user2");
            System.out.println(userEntity);

    什么是SpringIOC底层实现原理

    1.读取beanXML配置文件

    2.使用beanId查找bean配置,并获取配置文件中class地址。

    3.使用Java反射技术实例化对象

    4.获取属性配置,使用反射技术进行赋值。

    详细步骤:

    1.利用传入的参数获取xml文件的流,并且利用dom4j解析成Document对象

    2.对于Document对象获取根元素对象<beans>后对下面的<bean>标签进行遍历,判断是否有符合的id.

    3.如果找到对应的id,相当于找到了一个Element元素,开始创建对象,先获取class属性,根据属性值利用反射建立对象.

    4.遍历<bean>标签下的property标签,并对属性赋值.注意,需要单独处理int,float类型的属性.因为在xml配置中这些属性都是以字符串的形式来配置的,因此需要额外处理.

    5.如果属性property标签有ref属性,说明某个属性的值是一个对象,那么根据id(ref属性的值)去获取ref对应的对象,再给属性赋值.

    6.返回建立的对象,如果没有对应的id,或者<beans>下没有子标签都会返回null

    Maven的jar包依赖:

      <dependencies>
            <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>3.4</version>
            </dependency>
            <dependency>
                <groupId>org.dom4j</groupId>
                <artifactId>dom4j</artifactId>
                <version>2.0.0</version>
            </dependency>
        </dependencies>

    建立实体类:

    package com.hongmoshui.service;
    
    public class User extends Object
    {
    
        private String id;
    
        private String name;
    
        public User(String id)
        {
            System.out.println("有参构造函数, id:" + id);
            this.id = id;
        }
    
        public User()
        {
            System.out.println("无参构造函数...");
        }
    
        public String getId()
        {
    
            return id;
        }
    
        public void setId(String id)
        {
    
            this.id = id;
        }
    
        public String getName()
        {
    
            return name;
        }
    
        public void setName(String name)
        {
    
            this.name = name;
        }
    
        @Override
        public String toString()
        {
            return "User [id=" + id + ", name=" + name + "]";
        }
    
    }

    xml文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="    
         http://www.springframework.org/schema/beans     
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    
         http://www.springframework.org/schema/tx     
         http://www.springframework.org/schema/tx/spring-tx-3.0.xsd    
         http://www.springframework.org/schema/aop     
         http://www.springframework.org/schema/aop/spring-aop-3.0.xsd    
         http://www.springframework.org/schema/context    
         http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
        <bean id="user1" class="com.hongmoshui.service.User">
            <property name="id" value="0001"></property>
            <property name="name" value="红墨水001"></property>
        </bean>
        <bean id="user2" class="com.hongmoshui.service.User">
            <property name="id" value="0002"></property>
            <property name="name" value="红墨水002"></property>
        </bean>
    </beans>   

    代码:

    package com.hongmoshui.service;
    
    import java.lang.reflect.Field;
    import java.util.List;
    
    import org.dom4j.Document;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    import org.springframework.util.StringUtils;
    
    public class Text
    {
    
        private String pathXml = null;
    
        public Text(String pathXml)
        {
            this.pathXml = pathXml;
        }
    
        public Object getBean(String beanId) throws Exception
        {
            if (StringUtils.isEmpty(beanId))
            {
                throw new Exception("beanId is null");
            }
            SAXReader saxReader = new SAXReader();
            Document read = saxReader.read(new File(this.getClass().getClassLoader().getResource(pathXml).getPath()));
            // 获取到根节点
            Element rootElement = read.getRootElement();
            // 根节点下所有的子节点
            List<Element> elements = rootElement.elements();
            for (Element element : elements)
            {
                // 获取到节点上的属性
                String id = element.attributeValue("id");
                if (StringUtils.isEmpty(id))
                {
                    continue;
                }
                if (!id.equals(beanId))
                {
                    continue;
                }
    
                // 使用java反射机制初始化对象
                String beanClass = element.attributeValue("class");
                Class<?> forName = Class.forName(beanClass);
                Object newInstance = forName.newInstance();
                List<Element> propertyElementList = element.elements();
                for (Element el : propertyElementList)
                {
                    String name = el.attributeValue("name");
                    String value = el.attributeValue("value");
                    Field declaredField = forName.getDeclaredField(name);
                    declaredField.setAccessible(true);
                    declaredField.set(newInstance, value);
                }
                return newInstance;
    
            }
            return null;
        }
    
        public static void main(String[] args) throws Exception
        {
            Text classPath = new Text("applicationContext.xml");
            User user = (User) classPath.getBean("user2");
            System.out.println(user.toString());
    
        }
    
    }
  • 相关阅读:
    Codeforces Round #452 F. Letters Removing
    bzoj 1492: [NOI2007]货币兑换Cash
    bzoj 4016: [FJOI2014]最短路径树问题
    bzoj 2109: [Noi2010]Plane 航空管制
    bzoj 1058: [ZJOI2007]报表统计
    bzoj 1016: [JSOI2008]最小生成树计数
    bzoj 1013: [JSOI2008]球形空间产生器sphere
    bzoj 1758: [Wc2010]重建计划
    bzoj 2337: [HNOI2011]XOR和路径
    一本通1668取石子
  • 原文地址:https://www.cnblogs.com/hongmoshui/p/10984024.html
Copyright © 2011-2022 走看看