CCF认证2014032-窗口

本文介绍两种处理窗口管理和点击响应的算法,一种通过初始化屏幕并更新窗口编号实现,另一种使用链表维护窗口顺序,适用于窗口自底向上显示并可调整前后顺序的场景。

本人初学,水平有限,若有不足,恳请赐教!

1.方法1

根据题意,所有窗口的输入都是自底向上的,选中某个窗口此窗口会置为最顶端且其他窗口相对层叠次序不变。我们可以模拟这个过程。首先,在输入窗口坐标时令屏幕上此窗口范围内的所有点全部初始化为此窗口的编号,并且后输入的窗口可以覆盖之前的已有的窗口编号(画家算法),根据输入顺序恰好可以得到所有窗口的初始状态。然后,后续的点击操作如果选定的是某个窗口则输出此点的编号(即窗口的编号),并且对其进行“重染色”即根据窗口坐标重新对屏幕进行编号覆盖操作。如此反复即可得到正确结果。

显然,此方法存在大量的赋值操作,因此其时空复杂度均不高。

具体代码如下:

#include <iostream>
#include <vector>

using namespace std;

int mp[2600][1500];

typedef struct Point
{
	int x, y;
	Point(int x = 0, int y = 0) :x(x), y(y) {}
}Point;

int main()
{
	//FILE *stream;
	//freopen_s(&stream, "data.txt", "r", stdin);

	int n, m;
	cin >> n >> m;
	vector<pair<Point, Point>> vp(1); //存放窗口的两个坐标
	for(int i = 1; i <= n; i++)
	{
		int x1, y1, x2, y2;
		cin >> x1 >> y1 >> x2 >> y2;
		vp.push_back({Point(x1, y1), Point(x2, y2)});
		//窗口覆盖
		for(int x = x1; x <= x2; x++)
		{
			for(int y = y1; y <= y2; y++)
			{
				mp[x][y] = i;
			}
		}
	}
	while(m--)
	{
		int curx, cury;
		cin >> curx >> cury;
		//对应位置为0说明此处没有任何窗口
		if(!mp[curx][cury]) cout << "IGNORED" << endl;
		else
		{
			int t = mp[curx][cury];
			cout << t << endl;
			auto p1 = vp[t].first;
			auto p2 = vp[t].second;
			//重染色
			for(int x = p1.x; x <= p2.x; x++)
			{
				for(int y = p1.y; y <= p2.y; y++)
				{
					mp[x][y] = t;
				}
			}
		}
	}

	//fclose(stream);

	return 0;
}

2.方法2

考虑使用一个链表来依次存放各窗口的信息,链表由头到尾依次代表各窗口的从上到下的次序。对于每一次点击操作,都对链表由头到尾进行遍历,一旦发现符合条件的窗口则将其置于链表头部并输出窗口编号。

具体代码如下:

#include <iostream>
#include <list>

using namespace std;

typedef struct Windows
{
	int id; //窗口编号
	int x1, y1;
	int x2, y2;
	Windows(int id, int x1, int y1, int x2, int y2) :
		id(id), x1(x1), y1(y1), x2(x2), y2(y2)
	{}
}Windows;

int main()
{
	//FILE *stream;
	//freopen_s(&stream, "data.txt", "r", stdin);

	int n, m;
	cin >> n >> m;
	list<Windows> lw;
	for(int i = 1; i <= n; i++)
	{
		int x1, y1, x2, y2;
		cin >> x1 >> y1 >> x2 >> y2;
		//头插法插入各结点,从头到尾为从窗口由上到下的次序
		lw.push_front(Windows(i, x1, y1, x2, y2));
	}
	while(m--)
	{
		int x, y;
		cin >> x >> y;
		auto iter = lw.begin();
		//注意不要在循环结构内修改链表结构,不然会出错
		for(; iter != lw.end(); iter++)
		{
			int x1, y1, x2, y2;
			x1 = iter->x1, y1 = iter->y1, x2 = iter->x2, y2 = iter->y2;
			if(x1 <= x && x <= x2 && y1 <= y && y <= y2)
			{
				break; //一旦发现符合条件的窗口则跳出循环
			}
		}
		//没有找到符合要求的窗口则输出"IGNORED"
		if(iter == lw.end()) cout << "IGNORED" << endl;
		//否则输出窗口编号并调整链表
		else
		{
			cout << iter->id << endl;
			Windows t = *iter;
			lw.push_front(t);
			lw.erase(iter);
		}
	}

	//fclose(stream);

	return 0;
}

 

### CCF CSP认证的时间安排报名流程 CCF CSP(软件能力认证)是由中国计算机学会主办的一项针对个人编程能力和算法设计水平的测试活动。以下是关于其时间安排和报名流程的具体说明: #### 时间安排 CCF CSP认证每年举行三次,分别在 **3月**、**9月** 和 **12月** 进行[^1]。每次考试包含五道题目,主要考察本科阶段学习到的基础数据结构算法知识。 具体日期会由官方提前公布,在考前几个月可以通过 CCF 官方网站查询具体的考试时间和地点信息[^2]。 #### 报名流程 1. 登录 CCF 官网并注册账号。 2. 在指定时间内完成在线报名操作,并缴纳相应的费用。 3. 考试当天携带有效身份证件前往指定考点参加考试。 需要注意的是,考生需密切关注官网发布的最新动态以及各批次考试的确切时间节点。 ```python import datetime def check_exam_dates(): current_year = datetime.datetime.now().year exam_months = [3, 9, 12] upcoming_exams = [(current_year, month) for month in exam_months if month >= datetime.datetime.now().month] if not upcoming_exams: next_year = current_year + 1 upcoming_exams = [(next_year, month) for month in exam_months] return upcoming_exams upcoming_exams = check_exam_dates() print(f"Upcoming CCF CSP exams are scheduled for the following months of {', '.join([str(month) for _, month in upcoming_exams])}.") ``` 上述代码可以用来帮助用户查看即将到来的 CCF CSP 认证考试月份。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值