Counting Islands II_太阁竞赛C

本文介绍了一个关于在二维网格中填充陆地形成岛屿的问题,并通过并查集算法来跟踪每周填充后形成的岛屿数量变化。问题设定在一个1000x1000的网格上,每星期填充一个单元格,目标是计算每个星期结束后形成的岛屿数量。
题目3 : Counting Islands II
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
Country H is going to carry out a huge artificial islands project. The project region is divided into a 1000x1000 grid. The whole project will last for N weeks. Each week one unit area of sea will be filled with land.


As a result, new islands (an island consists of all connected land in 4 -- up, down, left and right -- directions) emerges in this region. Suppose the coordinates of the filled units are (0, 0), (1, 1), (1, 0). Then after the first week there is one island:  


#...
....
....
....
After the second week there are two islands:  


#...
.#..
....
....
After the three week the two previous islands are connected by the newly filled land and thus merge into one bigger island:


#...
##..
....
....
Your task is track the number of islands after each week's land filling.  


输入
The first line contains an integer N denoting the number of weeks. (1 ≤ N ≤ 100000)  


Each of the following N lines contains two integer x and y denoting the coordinates of the filled area.  (0 ≤ x, y < 1000)


输出
For each week output the number of islands after that week's land filling.


样例输入
3  
0 0   
1 1   
1 0   
样例输出
1  
2  

1  


【我的程序】

#include <iostream>
using namespace std;

long int n, num=0, a[1000000]={0}, aSize[1000000]={0};
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};

long int findID(long int x)
{
    while (a[x]!=x) x=a[x]=a[a[x]];
    return x;
}

void unionID(long int x, long int y)
{
    x=findID(x); y=findID(y);
    if (x==y) return;
    if (aSize[x]<aSize[y]) {a[x]=y; aSize[y]+=aSize[x];}
    else {a[y]=x; aSize[x]+=aSize[y];}
    num--;
}

int check(int x, int y)
{
    if (x>=0 && x<1000 && y>=0 && y<1000 && aSize[x*1000+y]>0) return 1; else return 0;
}

int main()
{
    long int i,p,q;
    cin>>n;

    for (i=0;i<n;i++)
    {
        cin>>p >>q;
        a[p*1000+q]=p*1000+q;
        aSize[p*1000+q]=1;
        num++;

        for (int j=0;j<4;j++)
            if (check(p+dx[j],q+dy[j])) unionID(p*1000+q,(p+dx[j])*1000+q+dy[j]);

        cout<<num <<endl;
    }

    return 0;
}


以下是使用 `mongosh` 在 `vms_trace_point` 数据库中创建两张表(集合)并插入数据、创建索引的完整步骤: --- ### **1. 切换到目标数据库** ```javascript use vms_trace_point ``` --- ### **2. 创建集合并插入数据** #### **(1) 创建 `smart_data_fault_recognition_info` 并插入数据** ```javascript db.smart_data_fault_recognition_info.insertOne({ dev_id: "device001", channel: 1, deviceId: "sensor123", timestamp_start: new Date("2023-10-01T10:00:00Z"), timestamp_end: new Date("2023-10-01T11:00:00Z"), type_num: 5, number: 100, expire_time: new Date("2023-11-01T00:00:00Z") // TTL索引的过期时间 }); ``` #### **(2) 创建 `peoplecounting_fault_recognition_info` 并插入数据** ```javascript db.peoplecounting_fault_recognition_info.insertOne({ dev_id: "device002", channel: 2, deviceId: "camera456", timestamp_start: new Date("2023-10-01T12:00:00Z"), timestamp_end: new Date("2023-10-01T13:00:00Z"), low_confidence_num: 10, middle_confidence_num: 20, high_confidence_num: 30, use_num: 50, useless_num: 5, expire_time: new Date("2023-11-01T00:00:00Z") // TTL索引的过期时间 }); ``` --- ### **3. 创建索引** #### **(1) 为 `smart_data_fault_recognition_info` 创建索引** - **复合索引**(`dev_id`, `timestamp_start`, `type_num`): ```javascript db.smart_data_fault_recognition_info.createIndex( { dev_id: 1, timestamp_start: 1, type_num: 1 }, { name: "idx_dev_timestamp_type" } ); ``` - **TTL索引**(`expire_time`,文档过期后自动删除): ```javascript db.smart_data_fault_recognition_info.createIndex( { expire_time: 1 }, { expireAfterSeconds: 0, name: "idx_expire_time" } ); ``` #### **(2) 为 `peoplecounting_fault_recognition_info` 创建索引** - **复合索引**(`dev_id`, `timestamp_start`): ```javascript db.peoplecounting_fault_recognition_info.createIndex( { dev_id: 1, timestamp_start: 1 }, { name: "idx_dev_timestamp" } ); ``` - **TTL索引**(`expire_time`): ```javascript db.peoplecounting_fault_recognition_info.createIndex( { expire_time: 1 }, { expireAfterSeconds: 0, name: "idx_expire_time" } ); ``` --- ### **4. 验证操作** #### **(1) 查看集合中的数据** ```javascript db.smart_data_fault_recognition_info.find().pretty(); db.peoplecounting_fault_recognition_info.find().pretty(); ``` #### **(2) 查看索引** ```javascript db.smart_data_fault_recognition_info.getIndexes(); db.peoplecounting_fault_recognition_info.getIndexes(); ``` --- ### **关键说明** 1. **TTL索引**: - `expireAfterSeconds: 0` 表示文档的 `expire_time` 字段值一到,立即删除。 - MongoDB的TTL后台线程默认每60秒运行一次,删除非即时生效。 2. **复合索引字段顺序**: - 复合索引的字段顺序影响查询效率。例如 `{ dev_id: 1, timestamp_start: 1 }` 适合按 `dev_id` 和时间范围查询的场景。 3. **时间字段类型**: - 示例中使用 `new Date()` 存储为 `ISODate` 类型,支持日期范围查询和聚合操作。 4. **字段名一致性**: - 注意 `smart_data_fault_recognition_info` 的复合索引中使用了 `timestamp_start`,但问题描述中提到的是 `timestamp`。如果实际字段名为 `timestamp`,请调整索引定义: ```javascript db.smart_data_fault_recognition_info.createIndex( { dev_id: 1, timestamp: 1, type_num: 1 } ); ``` --- ### **完整脚本** 将以下脚本保存为 `.js` 文件并通过 `mongosh` 执行: ```javascript // 切换数据库 use vms_trace_point; // 插入数据 db.smart_data_fault_recognition_info.insertOne({ dev_id: "device001", channel: 1, deviceId: "sensor123", timestamp_start: new Date("2023-10-01T10:00:00Z"), timestamp_end: new Date("2023-10-01T11:00:00Z"), type_num: 5, number: 100, expire_time: new Date("2023-11-01T00:00:00Z") }); db.peoplecounting_fault_recognition_info.insertOne({ dev_id: "device002", channel: 2, deviceId: "camera456", timestamp_start: new Date("2023-10-01T12:00:00Z"), timestamp_end: new Date("2023-10-01T13:00:00Z"), low_confidence_num: 10, middle_confidence_num: 20, high_confidence_num: 30, use_num: 50, useless_num: 5, expire_time: new Date("2023-11-01T00:00:00Z") }); // 创建索引 db.smart_data_fault_recognition_info.createIndex( { dev_id: 1, timestamp_start: 1, type_num: 1 }, { name: "idx_dev_timestamp_type" } ); db.smart_data_fault_recognition_info.createIndex( { expire_time: 1 }, { expireAfterSeconds: 0, name: "idx_expire_time" } ); db.peoplecounting_fault_recognition_info.createIndex( { dev_id: 1, timestamp_start: 1 }, { name: "idx_dev_timestamp" } ); db.peoplecounting_fault_recognition_info.createIndex( { expire_time: 1 }, { expireAfterSeconds: 0, name: "idx_expire_time" } ); // 验证 print("smart_data_fault_recognition_info 数据:"); db.smart_data_fault_recognition_info.find().forEach(printjson); print("\npeoplecounting_fault_recognition_info 数据:"); db.peoplecounting_fault_recognition_info.find().forEach(printjson); print("\n索引列表:"); printjson(db.smart_data_fault_recognition_info.getIndexes()); printjson(db.peoplecounting_fault_recognition_info.getIndexes()); ``` 执行方式: ```bash mongosh script.js ``` --- ### **总结** - 使用 `insertOne` 插入单条数据。 - 通过 `createIndex` 创建复合索引和TTL索引。 - TTL索引的 `expireAfterSeconds: 0` 表示按字段值立即过期。 - 复合索引字段顺序需根据查询模式优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值