Faraway(HDU-6639)
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), 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|)modki=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), denoting the number of test cases.
In each test case, there are two integers n,m(1≤n≤10,1≤m≤109) in the first line, denoting the number of soldiers and the upper bound of xe,ye.
For the next n lines, each line contains four integers xi,yi,ki,ti(0≤xi,yi≤m,2≤ki≤5,0≤ti<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 3Sample Output
10
0
题意:t 组数据,每组有 n 个式子 (|x[i]-x|+|y[i]-y|)%k[i]=t[i],每组数据给出这个式子的 x[i]、y[i]、k[i]、t[i],求满足这 n 个的解 {x,y} 的个数,要求 x、y 的范围为 0~m
思路:
对于式子 (|x[i]-x|+|y[i]-y|)%k[i]=t[i] 来说,由于存在绝对值,那么首先要去绝对值
那么每个点 (x[i],y[i]) 会将平面分成 4 个部分,每个部分中的距离表达式都没有绝对值符号,那么就分成了 n^2 个区域
然后枚举每个区域,计算该区域中可能的终点(x[e],y[e])的数量,由于 1<=k[i]<=5,0<=t[i]<=4,可以发现 LCM(2,3,4,5)=60,因此只需要枚举 x[e]、y[e] 模 60 的余数,然后计算有多少个点即可
Source Program
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<unordered_map>
#include<bitset>
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
#define Pair pair<int,int>
LL quickPow(LL a,LL b){ LL res=1; while(b){if(b&1)res*=a; a*=a; b>>=1;} return res; }
LL multMod(LL a,LL b,LL mod){ a%=mod; b%=mod; LL res=0; while(b){if(b&1)res=(res+a)%mod; a=(a<<=1)%mod; b>>=1; } return res%mod;}
LL quickPowMod(LL a, LL b,LL mod){ LL res=1,k=a; while(b){if((b&1))res=multMod(res,k,mod)%mod; k=multMod(k,k,mod)%mod; b>>=1;} return res%mod;}
LL getInv(LL a,LL mod){ return quickPowMod(a,mod-2,mod); }
LL GCD(LL x,LL y){ return !y?x:GCD(y,x%y); }
LL LCM(LL x,LL y){ return x/GCD(x,y)*y; }
const double EPS = 1E-10;
const int MOD = 998244353;
const int N = 1000+5;
const int dx[] = {-1,1,0,0,1,-1,1,1};
const int dy[] = {0,0,-1,1,-1,1,-1,1};
using namespace std;
int a[N], b[N];
struct Node {
int x, y, k, t;
} node[N];
bool judge(int x, int y,int n) {
for (int i = 1; i <= n; i++)
if ((abs(x - node[i].x) + abs(y - node[i].y)) % node[i].k != node[i].t)
return 0;
return 1;
}
int cal(int left, int right) {
right -= left + 1;
if (right < 0)
return 0;
return right / 60 + 1;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n,m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d%d%d%d", &node[i].x, &node[i].y, &node[i].k, &node[i].t);
a[i] = node[i].x;
b[i] = node[i].y;
}
a[n+1]=m+1;
b[n+1]=m+1;
sort(a + 1, a + n + 1 + 1);
sort(b + 1, b + n + 1 + 1);
LL res = 0;
for (int i = 0; i <= n; i++) {//分为n^2个区域
if (a[i] < a[i + 1]) { //防止区域重复
for (int j = 0; j <= n; j++) {//分为n^2个区域
if (b[j] < b[j + 1]) { //防止区域重复
for (int x = 0; x < 60; x++) { //枚举终点坐标x的余数
for (int y = 0; y < 60; y++) { //枚举终点左边y的余数
int ex=a[i]+x;
int ey=b[j]+y;
if (judge(ex, ey, n)) { // 统计区域中有多少余数
LL ansX=cal(ex,a[i+1]);
LL ansY=cal(ey,b[j+1]);
res += 1LL * ansX *ansY;
}
}
}
}
}
}
}
printf("%lld\n", res);
}
return 0;
}