玲珑oj 1143

来源:互联网 发布:mac系统cdr文件下载 编辑:程序博客网 时间:2024/05/18 09:25

Description

今HH考完了期末考试,他在教学楼里闲逛,他看着教学楼里一间间的教室,于是开始思考:
如果从一个坐标为 (x1,y1,z1)的教室走到(x2,y2,z2)的距离为|x1 - x2| + |y1 - y2| + |z1 - z2|
那么有多少对教室之间的距离是不超过R的呢?

Input

第一行是一个整数T(1≤T≤10), 表示有T组数据

接下来是T组数据,对于每组数据:

第一行是两个整数n,q(1≤n≤5×104,1≤q≤103), 表示有n间教室, q次询问.

接下来是n行, 每行3个整数xi,yi,zi(0≤xi,yi,zi≤10),表示这间教室的坐标.

最后是q行,每行一个整数R(0≤R≤109),意思见描述.

Output

对于每个询问输出一行一个整数,表示有多少对教室满足题目所述的距离关系.

Sample Input

1
3 3
0 0 0
1 1 1
1 1 1
1
2
3

Sample Output

1
1
3

Hint

对于样例,1号教室和2号教室之间的距离为3, 1号和3号之间的距离为3, 2号和3号之间的距离为0

题意

题解:

由于n的范围 所以n^2暴力是不行的 但是坐标只有0到10 可以从这里下手
直接暴力预处理0-30所有可能的距离的种类数
对于相同的坐标点 他们之间的距离是0 所以一定要算上 对于不同的点 种类数为点1*点2 然后除以2 因为会重复计算
最后注意种类数会超int

AC代码

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long ll;ll vis[15][15][15];ll ans[33];int main(){    int t;    scanf("%d",&t);    while (t--){        memset(vis,0,sizeof(vis));        memset(ans,0,sizeof(ans));        int n,q;        int x,y,z;        scanf("%d%d",&n,&q);        for (int i = 0; i < n; ++i){            scanf("%d%d%d",&x,&y,&z);            vis[x][y][z]++;        }        /*直接预处理距离的种数*/        for (int a = 0; a <= 10; ++a){            for (int b = 0; b <= 10; ++b){                for (int c = 0; c <= 10; ++c){                    for (int i = 0; i <= 10; ++i){                        for (int j = 0; j <= 10; ++j){                            for (int k = 0; k <= 10; ++k){                                int d = abs(a-i)+abs(b-j)+abs(c-k);                                if (d==0&&vis[i][j][k]){                                    ans[d] += (vis[i][j][k])*(vis[i][j][k]-1)/2;                                }                                else if (vis[i][j][k]*vis[a][b][c]>0){                                    ans[d] += vis[i][j][k]*vis[a][b][c];                                }                            }                        }                    }                }            }        }        for (int i = 1; i <= 30; ++i) ans[i] =ans[i-1]+ans[i]/2;        int r;        while (q--){            scanf("%d",&r);            if(r>30)r=30;            printf("%lld\n",ans[r]);        }    }    return 0;}
原创粉丝点击