[HDU6639]Faraway

本文探讨了一种基于坐标和模运算的谜题解决方案,通过分析士兵们提供的信息,利用绝对值和模运算特性,设计算法确定目标位置的可能性。通过枚举和验证策略,解决了在限定范围内的坐标解数量问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 524288/524288 K (Java/Others)

分数:2100,本来是个傻逼题但是怪自己太蠢了没想明白。
Problem Description

n soldiers are dispatched to somewhere in Byteland. These soldiers are going to set off now, but the target location is not so clear.

Assume the target location is at (xe,ye)(x_e,y_e)(xe,ye), it is clear that xe,ye are both non-negative integers within [0,m]. For the i-th soldier, the only thing he knows is that (∣xi−xe∣+∣yi−ye∣)(|x_i−x_e|+|y_i−y_e|)(xixe+yiye) modmodmod ki=tik_i=t_iki=ti.

To find the correct target location, these soldiers are working on the information they have now. Please write a program to figure out the number of possible target locations.

Input
The first line of the input contains an integer T(1≤T≤10)T(1≤T≤10)T(1T10), denoting the number of test cases.

In each test case, there are two integers n,m(1≤n≤10,1≤m≤109)n,m(1≤n≤10,1≤m≤10^9)n,m(1n10,1m109) in the first line, denoting the number of soldiers and the upper bound of xe,yex_e,y_exe,ye.

For the next nnn lines, each line contains four integers xi,yi,ki,ti(0≤xi,yi≤m,2≤ki≤5,0≤ti&lt;ki)x_i,y_i,k_i,t_i(0≤x_i,y_i≤m,2≤k_i≤5,0≤t_i&lt;k_i)xi,yi,ki,ti(0xi,yim,2ki5,0ti<ki), denoting what each soldier knows.

Output
For each test case, print a single line containing an integer, denoting the number of possible target locations.

Sample Input

2
2 5
1 2 4 2
3 1 2 1
2 5
1 2 4 2
1 2 4 3

Sample Output

10
0

题意:
给定nnn个方程组成的方程组,形如,(∣xi−xe∣+∣yi−ye∣)(|x_i−x_e|+|y_i−y_e|)(xixe+yiye) modmodmod ki=tik_i=t_iki=ti
(xe,ye)(x_e,y_e)(xe,ye) (0&lt;=xe,ye&lt;=m)(0&lt;=x_e,y_e&lt;=m)(0<=xe,ye<=m)的方案数。

题解:
由于是绝对值,所以每个绝对值讲解空间切成了四份,最多是n2n^2n2份,那么我们将xix_ixiyiy_iyi排序之后枚举解空间,对于每个解空间求解的方案数。对于每个解空间,我们枚举xe,yex_e,y_exe,ye对60(2,3,4,5的最小公倍数)取模的结果,然后带入方程组验证。如果可行,那么求这个解在当前解空间内有多少个不同的方案,注意解空间可能会出现边界相交的情况,所以我们需要将区间变为前闭后开的防止重复计算。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll lcm=60LL,ans;
int n;
ll m,x[14],y[14],k[14],t[14];
ll ax[14],ay[14];
void calc(ll Lx,ll Rx,ll Ly,ll Ry){
    for(ll dx=0;dx<lcm;dx++){
        for(ll dy=0;dy<lcm;dy++){
            bool flag=1;
            ll xe=dx+Lx,ye=Ly+dy;
            for(int i=1;i<=n-1;i++){
                if((abs(x[i]-xe)+abs(y[i]-ye))%k[i]!=t[i]){
                    flag=0;
                    break;
                }
            }
            if(!flag)continue;
            ll cax=Rx-xe-1,cay=Ry-ye-1;
            if(cax<0)cax=0;
            else cax=cax/lcm+1;
            if(cay<0)cay=0;
            else cay=cay/lcm+1;
            ans+=cax*cay;
        }
    }
}
int w33ha(){
    scanf("%d%lld",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%lld%lld%lld%lld",&x[i],&y[i],&k[i],&t[i]);
        ax[i]=x[i];
        ay[i]=y[i];
    }
    ans=0;
    n++;
    ax[0]=0;ay[0]=0;
    ax[n]=m+1;ay[n]=m+1;
    sort(ax+1,ax+n+1);
    sort(ay+1,ay+n+1);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(ax[i]>=ax[i+1])continue;
            if(ay[j]>=ay[j+1])continue;
            calc(ax[i],ax[i+1],ay[j],ay[j+1]);
        }
    }
    printf("%lld\n",ans);
    return 0;
}
int main(){
    int T;scanf("%d",&T);
    while(T--)w33ha();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值