1 条题解

  • 0
    @ 2025-5-7 18:55:26

    题目分析

    我们需要确定在无限递归分割的矩形中,给定点的最终颜色。矩形的分割规则基于比例 hhvv,每次分割后部分子矩形的颜色会被翻转,并递归处理。

    解题思路

    1. 分割规则

      • 垂直线将矩形水平分割为比例为 h:1hh : 1-h 的两部分。
      • 水平线将矩形垂直分割为比例为 v:1vv : 1-v 的两部分。
      • 分割后,左上和右下的子矩形保持原色,其他两个子矩形颜色翻转并递归分割。
    2. 递归终止条件

      • 如果点位于左上或右下的子矩形,直接返回当前颜色。
      • 否则,递归处理左下或右上的子矩形,并翻转颜色。
    3. 坐标变换

      • 对于左下子矩形,递归时保持比例不变,坐标不变。
      • 对于右上子矩形,递归时坐标需要减去已分割的部分(hh2h \cdot h_2vv2v \cdot v_2)。

    关键公式

    • 分割位置
      • 水平分割点:hh2h \cdot h_2
      • 垂直分割点:vv2v \cdot v_2
    • 颜色翻转:每次递归翻转颜色(1c1 - c)。

    方法步骤

    1. 输入处理:读取矩形尺寸 HHVV 和比例参数 hhvv,以及查询点的数量 nn
    2. 递归判断:对于每个点,递归判断其所在子矩形的位置,决定是否翻转颜色。
    3. 输出结果:根据递归结果输出点的颜色(黑色或白色)。

    该方法通过递归和坐标变换高效地确定了无限分割后点的最终颜色。

    /* UVA10998 POJ2857 Flipping Colors */
    
    #include <iostream>
    #include <cstdio>
    
    using namespace std;
    
    double dfs(double h, double v, double h2, double v2, double x, double y, int c)
    {
    	double hh = h * h2;
    	double vv = v * v2;
    	if (x <= hh && y >= vv)	return c; // upper left
    	if (x >= hh && y <= vv)	return c; // lower right
    	if (x <= hh) 	// lower left
    		return dfs(h * h2, v * v2, h2, v2, x, y, 1 - c);
    	else			// upper right
    		return dfs(h * (1 - h2), v * (1 - v2), h2, v2, x - hh, y - vv, 1 - c);
    }
    
    int main()
    {
    	double h, v, h2, v2, x, y;
    	int n, caseno = 0;
    	while (scanf("%lf%lf%lf%lf", &h, &v, &h2, &v2) == 4 && h) {
    		scanf("%d", &n);
    		
    		printf("Case %d:\n", ++caseno);
    		for (int i = 0; i < n; i++) {
    			scanf("%lf%lf", &x, &y);
    			int ans = dfs(h, v, h2, v2, x, y, 1);
    			puts(ans ? "black" : "white");
    		}
    	}
    	
    	return 0;
    }
    • 1

    信息

    ID
    1857
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者