P1003 [NOIP 2011 提高组] 铺地毯

记录36

#include<bits/stdc++.h>
using namespace std;
struct node{
	int x,y,l,w;
};
int main(){
	int n,x1,y1,t=-1;
	cin>>n;
	node m[10010]={};
	for(int i=1;i<=n;i++){
		cin>>m[i].x>>m[i].y>>m[i].l>>m[i].w;
	}
	cin>>x1>>y1;
	for(int i=1;i<=n;i++){
if(m[i].x<=x1&&m[i].x+m[i].l>=x1&&m[i].y<=y1&&m[i].y+m[i].w>=y1)	t=i;
	}
	cout<<t;
	return 0;
} 

题目传送门https://www.luogu.com.cn/problem/P1003


突破点

现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设,后铺的地毯覆盖在前面已经铺好的地毯之上

👉后面的坐标覆盖前面的坐标

在矩形地毯边界和四个顶点上的点也算被地毯覆盖

👉边界限位置也得考虑进去


思路

  1. 结构体存储地毯信息
  2. 录入地毯信息
  3. 从前往后比对每块地毯的范围是否包括坐标点,更新编号

代码简析

#include<bits/stdc++.h>
using namespace std;
struct node{
	int x,y,l,w;
};
int main(){
	int n,x1,y1,t=-1;
	cin>>n;
	node m[10010]={};
	for(int i=1;i<=n;i++){
		cin>>m[i].x>>m[i].y>>m[i].l>>m[i].w;
	}
	...
	return 0;
} 

定义结构体,接着输入结构体

t用来存储符合条件的地毯编号,如果没有就输出-1,所以t赋值为-1

for循环从1到n,代表地毯的编号

#include<bits/stdc++.h>
using namespace std;
struct node{
	int x,y,l,w;
};
int main(){
	int n,x1,y1,t=-1;
	cin>>n;
	node m[10010]={};
	for(int i=1;i<=n;i++){
		cin>>m[i].x>>m[i].y>>m[i].l>>m[i].w;
	}
	cin>>x1>>y1;
	for(int i=1;i<=n;i++){
if(m[i].x<=x1&&m[i].x+m[i].l>=x1&&m[i].y<=y1&&m[i].y+m[i].w>=y1)	t=i;
	}
	cout<<t;
	return 0;
} 

输入目标x1y1

if(m[i].x<=x1&&m[i].x+m[i].l>=x1&&m[i].y<=y1&&m[i].y+m[i].w>=y1)  t=i;

判断输入的目标点,在不在地毯覆盖的范围内,在的话就存进t里面

最后输出t


补充

在C++中,结构体是竞赛编程的核心工具,以下是使用办法:


1. 基础定义与声明

struct Student {
    int id;
    string name;
    int score;
};

// 声明变量
Student s1;          // 未初始化,值随机
Student s2 = {1, "Alice", 95};  // C++11起可用列表初始化

竞赛提示:在CSP中,强烈建议初始化所有成员,避免随机值导致WA。


2. 成员访问与修改

s1.id = 2;           // 使用点号访问
s1.name = "Bob";
s1.score = 88;

cin >> s2.id >> s2.name >> s2.score;  // 直接输入
cout << s1.id << " " << s1.score;     // 直接输出

竞赛技巧:对于频繁访问的场景,可先用临时变量存储再统一处理,减少点号运算开销。


3. 构造函数(CSP高频用法)

struct Node {
    int x, y, dist;
    
    // 构造函数:简化初始化,避免遗漏成员
    Node(int _x, int _y, int _d) : x(_x), y(_y), dist(_d) {}
    
    // 默认构造函数(配合vector使用)
    Node() : x(0), y(0), dist(0) {}
};

// 使用
Node n1(1, 2, 3);      // 直接构造
vector<Node> nodes(10); // 需要默认构造函数

竞赛必用务必定义构造函数,特别是配合priority_queuevector时。


4. 运算符重载(排序与比较)

struct Student {
    int id, score;
    
    // 按分数降序排序(CSP最常见)
    bool operator < (const Student& other) const {
        return score > other.score;  // >表示降序
    }
    
    // 或按id升序
    bool operator < (const Student& other) const {
        return id < other.id;
    }
};

// 使用
vector<Student> v;
sort(v.begin(), v.end());  // 自动调用operator<
priority_queue<Student> pq; // 自动按重载规则排序

竞赛核心必须掌握运算符重载,是结构体排序和优先队列的基础。


5. 嵌套结构体

struct Point {
    int x, y;
};

struct Rectangle {
    Point topLeft;    // 嵌套结构体
    Point bottomRight;
    int area() const { // 成员函数
        return (bottomRight.x - topLeft.x) * (bottomRight.y - topLeft.y);
    }
};

Rectangle r = {{0,0}, {10,5}};
int a = r.area();     // 调用成员函数

竞赛应用:用于图论中的边结构、树结构等复杂数据建模。


6. 初始化列表(C++11)

struct Edge {
    int u, v, w;
};

// 列表初始化
Edge e1 = {1, 2, 3};
Edge e2{1, 2, 3};      // 更简洁

// 在容器中直接构造
vector<Edge> edges;
edges.push_back({1, 2, 3});  // 自动类型推导

竞赛提速:列表初始化代码更简洁,减少出错率。


7. 内存对齐与占用大小

struct A {
    char c;  // 1字节
    int i;   // 4字节(对齐后可能填充3字节)
};           // 实际可能占8字节

struct B {
    int i;
    char c;
};           // 可能占5字节或8字节

cout << sizeof(A) << " " << sizeof(B);  // 输出可能不同

竞赛注意:在内存敏感题中(如状态压缩),注意成员声明顺序,减少填充字节。


8. const与引用使用

struct Data {
    int val;
    void print() const {  // const成员函数
        cout << val;
    }
};

// 传参优化
void process(const Student& s) {  // const引用避免拷贝
    cout << s.id;  // 只读,不可修改
}

竞赛优化传递结构体务必使用 const 引用,避免大结构体拷贝开销。


9. 与STL容器配合使用

struct Node {
    int id, dist;
    bool operator < (const Node& other) const {
        return dist > other.dist;
    }
};

// 在优先队列中使用
priority_queue<Node> pq;
pq.push({1, 0});  // 自动按dist排序

// 在map中作为键值
map<string, Student> mp;
mp["Alice"] = {1, "Alice", 95};

// 在unordered_map中使用(需自定义哈希)
struct Hash {
    size_t operator()(const Node& n) const {
        return n.id * 100000 + n.dist;
    }
};
unordered_map<Node, int, Hash> ump;

竞赛核心:结构体与STL结合是解题标配,务必会重载运算符


10. C++17结构化绑定(CSP-S可能用到)

struct Result {
    int sum, max, min;
};

Result calc(const vector<int>& v) {
    // ... 计算逻辑
    return {sum, max, min};
}

// 解构返回的结构体
auto [s, mx, mn] = calc(v);  // 直接获取三个成员
cout << s << " " << mx << " " << mn;

竞赛前瞻:新编译器已支持,可简化多返回值处理。


CSP竞赛核心总结

场景推荐做法禁忌
定义结构体必须包含构造函数不要遗漏默认构造
排序/优先队列必须重载 < 运算符不要返回 score < other.score(升序)
函数传参必须用 const 引用不要直接传值(大结构体)
初始化优先使用列表初始化不要依赖成员默认初始化
比较操作重载运算符而非全局函数不要写比较函数对象(繁琐)

万能竞赛模板

struct Node {
    int x, y, w;
    Node() {}  // 默认构造
    Node(int _x, int _y, int _w) : x(_x), y(_y), w(_w) {}
    
    bool operator < (const Node& other) const {
        return w < other.w;  // 按权重升序
    }
};

掌握以上十条,可覆盖CSP中99%的结构体应用场景。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值