uva12373 - Pair of Touching Circles

探讨如何在给定尺寸的矩形区域内,计算能够放置的两个不相交且完全包含在内的圆的不同组合方式。通过枚举圆心坐标差及半径来解决此问题。
部署运行你感兴趣的模型镜像

Given a rectangular grid of height H and width W. A problem setter wants to draw a pair of circlesinside the rectangle so that they touch each other but do not share common area and both the circlesare completely inside the rectangle. As the problem setter does not like precision he also wants theircenters on integer coordinates and their radii to be positive integers as well. How many different wayscan he draw such pair of circles? Two drawings are different from each other if any of the circles hasdifferent center location or radius.InputThe first line of input contains the number of test cases T (T ≤ 500). Each of the next T lines willcontain two integers H and W (0 < H, W ≤ 1000).OutputFor each line of input output the case number and the number of ways of drawing such pairs of circlesmaintaining the mentioned constraints. See sample output for exact formatting. The output will fitinto 64-bit signed integer.Illustration of case 3:Sample Input54 24 34 44 610 10Sample OutputCase 1: 1Case 2: 2Case 3: 6Case 4: 16Case 5: 496

  N*M的矩阵,两个相邻的圆,圆心和半径都要是整数,求这两个圆在矩阵中有多少种放置情况,位置和半径不同都算。

  这题坑了我一下午=。= 我竟然拿DP去做,因为一开始想错了,以为这两个圆的关系只能是横着或竖着,然而答案并不对。。怎么看我DP写的也没问题,后来才发现还可能有斜着的情况,比如两个圆心的连线是勾股三角形斜边的时候就可以。。然后我又去特判这种情况,反正最后过了样例交上去WA。。最后一想,用什么DP啊,直接枚举两个圆心的坐标差,如果圆心距离是整数的话,再枚举半径长度,算出包含这两个圆的最小矩阵是多大,再看整个矩阵中能包含多少个这样的小矩阵,特别要注意的是如果两个圆大小相同那么对称之后还是相同,这种要特判一下。交上去TLE。。发现间距只用枚举到N,M的一半,改了后终于AC。。

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
typedef long long LL;

const LL MAXN=1010;
const LL INF=0x3f3f3f3f;
const LL SIGMA_SIZE=28;

LL T,N,M;

LL solve(LL n,LL m){
    LL ret=0;
    for(LL i=0;i<=N/2;i++)
        for(LL j=0;j<=M/2;j++) if(i+j>0){
            LL t=i*i+j*j;
            LL sq=(LL)(sqrt(t)+0.5);
            if(sq*sq==t){
                for(LL r=1;r<=sq/2;r++){
                    LL x=max(i+sq,max(r*2,(sq-r)*2)),y=max(j+sq,max(r*2,(sq-r)*2));
                    LL tmp=(n-x+1)*(m-y+1);
                    if(n>=x&&m>=y){
                        if(i!=0&&j!=0){
                            if(r*2!=sq) ret+=tmp*4;
                            else ret+=tmp*2;
                        }
                        else{
                            if(r*2!=sq) ret+=tmp*2;
                            else ret+=tmp;
                        }
                    }
                }
            }
        }
    return ret;
}

int main(){
    //freopen("in.txt","r",stdin);
    LL cas=0;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&N,&M);
        printf("Case %lld: %lld\n",++cas,solve(N,M));
    }
    return 0;
}


您可能感兴趣的与本文相关的镜像

Qwen-Image

Qwen-Image

图片生成
Qwen

Qwen-Image是阿里云通义千问团队于2025年8月发布的亿参数图像生成基础模型,其最大亮点是强大的复杂文本渲染和精确图像编辑能力,能够生成包含多行、段落级中英文文本的高保真图像

<think>我们正在解析日志信息:"pointerCount 0 -> 1, touching ids 0x00000000 -> 0x80000000, hovering ids 0x00000000 -> 0x00000000, canceled ids 0x00000000" 根据引用[3]中描述的InputReader处理流程,特别是CursorInputMapper::sync(对于触摸事件,可能是TouchInputMapper)的过程,我们可以推断syncTouch日志是触摸事件同步过程中的信息。 让我们解析每个部分: 1. pointerCount: 表示当前触摸点的数量。从0变为1,表示从没有触摸点到出现一个触摸点(例如手指触摸屏幕)。 2. touching ids: 表示当前处于触摸状态(按下或移动)的指针(手指)的ID的位掩码。从0x00000000(没有触摸)变为0x80000000。注意,0x80000000的二进制表示是10000000000000000000000000000000,即最高位为1,其余为0。在Android系统中,每个触摸点都有一个ID(从0开始),并且用一个32位的位掩码来表示哪些ID的触摸点处于触摸状态。这里最高位(第31位)被置为1,表示ID为31的触摸点处于触摸状态?但是通常我们不会有31个手指同时触摸(而且这里pointerCount=1)。实际上,在Android中,触摸点ID通常是从0开始分配的,所以这里可能是表示ID=0的触摸点?但是0x80000000对应的是第31位(从0开始计数),而不是第0位。 我们需要重新考虑:在Android源码中,触摸点的ID位掩码表示方法:每一位代表一个ID,例如ID=0对应最低位(0x00000001),ID=1对应0x00000002,...,ID=31对应0x80000000。所以0x80000000表示的是ID=31的触摸点。 然而,这里pointerCount只有1,为什么是ID=31?这可能是因为设备上报的触摸点ID就是31,或者可能是系统分配的一个较高的ID?但实际上,在一般使用中,第一个触摸点的ID通常是0。所以我们需要检查设备上报的触摸点ID。 3. hovering ids: 表示悬停状态的指针ID位掩码。这里保持0,表示没有触摸点处于悬停状态。 4. canceled ids: 表示被取消的指针ID位掩码。这里为0,表示没有触摸点被取消。 综上所述,这个日志表示了一个触摸事件:从没有触摸点变为一个触摸点(按下)。但是这个触摸点的ID是31(由touching ids的变化得知),而不是通常的0。 这可能是由于设备上报的触摸点ID就是31,或者系统内部分配的。在多点触摸中,每个触摸点都有一个唯一的ID,这个ID在整个触摸过程中保持不变(从按下到抬起)。ID的分配由设备驱动或输入子系统决定。 在Android的InputReader中,当一个新的触摸点出现时,会分配一个唯一的ID(在可用ID中选取最小的未被使用的ID)。但这里第一个触摸点就分配了31?这不太常见,因为通常从0开始分配。所以我们需要考虑另一种情况:位掩码的表示方式可能是按照ID的值来设置的,但这里的0x80000000可能表示的是最高位的ID,即第31号ID。 然而,在Android源码中,我们确实可以看到类似的处理。例如,在TouchInputMapper中的函数`assignExternalStylusId`和`getTouchIdBits`等,都是使用位掩码来表示ID集合。 可能的原因: - 设备驱动上报的触摸点数据中,该触摸点的ID就是31。 - 系统在分配ID时,由于某种原因(比如之前的触摸事件使用了0-30的ID,然后被释放了,然后这次分配了31)分配了31。但是这里pointerCount从0变成1,说明之前没有触摸点,所以应该分配一个最小的可用ID(通常是0)。除非0已经被保留(但这里不应该)。 因此,我们可能需要更多的上下文。但根据日志,我们可以确定的是:一个ID为31的触摸点被按下。 另外,注意到touching ids从0x00000000变为0x80000000,而hovering ids没有变化(都是0),canceled ids没有变化(0),符合一个触摸点按下的情况。 总结: - pointerCount 0->1: 触摸点数量从0增加到1。 - touching ids: 从没有触摸点变为ID为31的触摸点处于触摸状态。 - hovering ids: 没有悬停的触摸点。 - canceled ids: 没有触摸点被取消。 这个日志记录的是TouchInputMapper在同步触摸状态时发生的变化。 注意:在Android系统中,触摸事件的处理流程是: InputReader从设备读取事件(通过EventHub)-> 交给对应的InputMapper(这里是TouchInputMapper)处理 -> 在sync过程中更新触摸状态 -> 生成RawEvent并传递给InputDispatcher。 因此,syncTouch日志就是在同步过程中打印的,用于显示当前同步前后触摸状态的变化。 参考引用[3]中提到的InputReader处理流程,我们可以知道这个日志发生在InputReader::processEventsForDeviceLocked过程中,具体在TouchInputMapper::sync方法内(类似于CursorInputMapper::sync)。 这样,我们就解析了这条日志的含义。 注意:在实际分析中,还需要查看前后的日志,以确定这个触摸点的后续事件(移动、抬起等)。 最后,根据指令要求,生成相关问题: </think>### InputReader syncTouch日志信息解析 您提供的日志片段`pointerCount 0 -> 1, touching ids 0x00000000 -> 0x80000000, hovering ids 0x00000000 -> 0x00000000, canceled ids 0x00000000`描述了触摸事件的同步状态变化,具体解析如下: 1. **pointerCount 0 -> 1** 表示从**无触摸点**变为检测到**1个触摸点**。这是触摸事件的起始状态(如手指首次接触屏幕)。 2. **touching ids 0x00000000 -> 0x80000000** - `0x00000000`:初始无活跃触摸点 - `0x80000000`:转换为**触摸点ID=31**(十六进制位掩码,最高位对应ID 31)。 **含义**:系统分配了触摸点ID 31(通常表示第一个触点),状态为`ACTION_DOWN`[^1][^3]。 3. **hovering ids 0x00000000 -> 0x00000000** 保持为0,表示**无悬停状态**(如手指悬浮在屏幕上未接触)。 4. **canceled ids 0x00000000** 保持为0,表示**无触摸点被取消**(如未发生`ACTION_CANCEL`事件)。 #### 完整流程说明: 1. 当用户手指触碰屏幕时,输入设备上报原始事件。 2. InputReader通过`EventHub`获取事件(如引用[1]的设备信息)[^1]。 3. `TouchInputMapper`处理事件并调用`syncTouch()`更新状态: - 分配触摸点ID(此处ID=31) - 标记状态为`ACTION_DOWN` 4. 状态变化通过`InputDispatcher`传递(如引用[2]的`notifyKey`流程)[^2],最终驱动UI响应。 #### 关键点: - **ID分配机制**:Android使用32位掩码管理触点,`0x80000000`对应ID 31(最高位),说明系统当前分配的ID值较高,可能因历史ID未被释放[^3]。 - **状态转换**:此日志表明**新的触摸事件开始**,后续可能伴随`pointerMove`或`ACTION_UP`事件。 --- ### 相关问题 1. 如何跟踪触摸事件从InputReader到应用层的完整传递路径? 2. 触摸点ID的分配策略是什么?为何有时会分配高数值ID(如31)? 3. 什么情况下会导致触摸事件被标记为`canceled ids`? 4. `hovering ids`在哪些输入设备场景下会被触发? --- ### 附录:相关流程示意图 ``` EventHub → InputReader → TouchInputMapper::syncTouch() ↓ 状态更新 (pointerCount, touching IDs) ↓ InputDispatcher → 应用层处理 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值