【简单算法】窗口模拟点击

骂人这是本人重新开始使用Visual C++ 6.0写出的第一个程序

【题意】在计算机屏幕上,有 N 个窗口。窗口的边界上的点也属于该窗口。窗口之间有层次的区别,在多于一个窗口重叠的区域里,只会显示位于顶层的窗口里的内容。当你用鼠标点击某个点的时候,若其在窗口内,你就选择了处于被点击位置所属的最顶层窗口,并且这个窗口就会被移到所有窗口的顶层,而剩余的窗口的层次顺序不变,如果你点击的位置不属于任何窗口计算机就会忽略你这次点击。编写一个程序模拟点击窗口的过程:先从标准输入读入窗口的个数,窗口编号和位置(以窗口的左上角和右下角的坐标表示,先输入的窗口层次高),然后读入点击的次数和位置(以点击的坐标表示),编写程序求得经过上述点击后的窗口叠放次序。

【假设】:

1、     屏幕左下角作为 X 轴和 Y 轴坐标原点,即坐标为(0,0),所有输入的坐标       数值都是整数,并且都大于等于 0,小于等于1000。

2、     输出窗口的叠放次序时从最后点击后最顶层的窗口编号开始按层次依次输出;

3、     输入的窗口个数大于 0 并且小于等于 10,点击次数大于 0并且小于等于 20。

 

【输入】第一行窗口个数 n,接下来 n 行每行一个窗口的编号、左下角坐标、右上角坐标。

接下来一行点击次数 k,接下来 k行每行一个点击坐标。

【输出】一行 n个数字,表示 K 次点击后按层次排列的窗口编号,空格隔开。

行末空格与文末换行可有可无。

样例:

【标准输入】
4 
1	43 31 70 56 
2	50 24 80 50 
3	23 13 63 42 
4	57 36 90 52 
5 
47 28 
73 40 
68 32 
82 43 
27 49 
【标准输出】
4 2 3 1

思路:

用二维数组screen来存储窗口的id,点击某一个位置时,从screen得到该位置的窗口ID,然后将其置顶即可

(不用screen数组存储也可以,遇到点击事件时从最顶端的窗口开始逐个判断光标是否在本窗口内)

#include <stdio.h>
#include <memory.h>
#include <vector>
using namespace std;

struct Window {
	int id;
	int x1, y1;
	int x2, y2;
} windows[10];

vector<int> seqs;		// window sequence, seqs[0] is the bottom

int screen[1000][1000];	// window id of each pixel in screen, -1 mean no window

int main() {
	freopen("C:\\input1.txt", "r", stdin);
	int i, j, k;
	int window_count;
	int click_count;
	scanf("%d", &window_count);
	memset(screen, -1, sizeof(screen));
	for (i = 0; i < window_count; i++) {
		scanf("%d %d %d %d %d", &windows[i].id, &windows[i].x1, &windows[i].y1, &windows[i].x2, &windows[i].y2);
	}
	// put all windows on screen
	for (k = window_count - 1; k >= 0; k--) {
		seqs.push_back(k);
		for (i = windows[k].x1; i <= windows[k].x2; i++) {
			for (j = windows[k].y1; j <= windows[k].y2; j++) {
				screen[i][j] = windows[k].id;
			}
		}
	}
	scanf("%d", &click_count);
	// read clicks
	int click_x, click_y;
	for (int f = 0; f < click_count; f++) {
		scanf("%d %d", &click_x, &click_y);
		if (screen[click_x][click_y] == -1) continue;
		// find the window in array
		for (j = 0; j < window_count; j++) {
			if (windows[j].id == screen[click_x][click_y]) {
				k = j;
				break;
			}
		}
		for (i = windows[k].x1; i <= windows[k].x2; i++) {
			for (j = windows[k].y1; j <= windows[k].y2; j++) {
				screen[i][j] = windows[k].id;
			}
		}
		// bring the window to top
		for (j = 0; j < seqs.size(); j++) {
			if (seqs[j] == k) {
				seqs.erase(seqs.begin() + j);
				seqs.push_back(k);
				break;
			}
		}
	}
	for (i = seqs.size() - 1; i >= 0; i--) {
		printf("%d ", windows[seqs[i]].id);
	}
	return 0;
}

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
停止等待ARQ算法是一种简单的错误控制协议,通常用于在数据传输过程中发现和纠正错误。下面是一个简单的Java程序,用于模拟停止等待ARQ算法的实现。 ```java import java.util.Random; public class StopAndWaitARQ { public static void main(String[] args) { int packetSize = 1000; // 数据包大小,单位为字节 int windowSize = 1; // 窗口大小,每次发送一个数据包 // 模拟数据传输过程 for (int i = 0; i < 10; i++) { // 发送数据包 boolean isACKReceived = false; int seqNum = i % 2; // 序列号为0或1 System.out.println("发送数据包:" + seqNum); // 模拟信道延迟和丢包 Random random = new Random(); int delay = random.nextInt(2000); // 延迟时间范围:0~2000毫秒 try { Thread.sleep(delay); } catch (InterruptedException e) { e.printStackTrace(); } if (random.nextDouble() > 0.2) { // 有80%的概率数据包会被成功接收,20%的概率数据包会丢失 isACKReceived = true; } // 接收ACK if (isACKReceived) { System.out.println("接收到ACK:" + seqNum); } else { System.out.println("未接收到ACK:" + seqNum + ",进行重传"); i--; // 重传当前数据包 } } } } ``` 该程序使用一个循环模拟了10次数据传输过程。在每次传输时,程序首先选择一个序列号来标识数据包,然后模拟信道延迟和丢包情况。如果数据包未丢失,则认为收到了ACK确认。如果未收到ACK确认,则触发重传,继续发送当前数据包。 请注意,该程序仅是一个简单的示例,仅用于展示停止等待ARQ算法的基本思想。真实的实现中,还需要考虑多个方面,例如超时重传、累积确认和滑动窗口等。这些细节可以根据具体需求进行扩展和修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值