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 , 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 .
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
, denoting the number of test cases.
In each test case, there are two integers in the first line, denoting the number of soldiers and the upper bound of .
For the next lines, each line contains four integers , 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
题意:
给定
个方程组成的方程组,形如,
求
的方案数。
题解:
由于是绝对值,所以每个绝对值讲解空间切成了四份,最多是
份,那么我们将
和
排序之后枚举解空间,对于每个解空间求解的方案数。对于每个解空间,我们枚举
对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;
}