Problem Description
度度熊最喜欢六边形的网格了!!!
上图由左至右依序是边长为 111, 222 以及 333 的六边形网格。
另外,每个六边形网格最左侧的格子称之为这个六边形网格的锚点,上图中每个六边形网格的锚点都以蓝色着色。
定义在六边形网格上的坐标系统:相对一个坐标为 (x,y)(x, y)(x,y) 的中心格子,其周围格子的坐标定义为下图中所示的值:
给定一个大小为 LLL 的六边形主网格,这个六边形主网格的锚点的坐标为 (1,L)(1, L)(1,L)。这个主网格中每一个格子上都有一个颜色,以 000 至 616161 之间的整数代表。对于这个主网格有 QQQ 个询问,每个询问将会询问这个主网格中某一个六边形子网格的范围中,包含有几个不一样的颜色。
一个询问以三个整数 <x,y,l><x, y, l><x,y,l> 来表示其中一个六边形的子网格,依序为其锚点的坐标 (x,y)(x, y)(x,y) 以及其大小 lll。例如,下图为一个大小 L=3L = 3L=3 的主网格,格子内部的数字为其坐标,而非格子的颜色。绿色边框所包围的子网格是一个锚点坐标为 (5,3)(5, 3)(5,3),大小 l=2l = 2l=2 的子网格,以 <5,3,2><5, 3, 2><5,3,2> 表示,同时,红色边框表示 <3,1,1><3, 1, 1><3,1,1> 的子网格。
Input
输入的第一行有一个正整数 TTT,代表接下来有几笔测试资料。
对于每笔测试资料: 第一行有一个正整数 LLL。 接下来的 2L−12L - 12L−1 行输入代表一个大小为 LLL 的六边形网格。 六边形网格将会透过下列的过程转换至输入的格式:
- 将每格内代表颜色的数字 000~616161 按照 0-9a-zA-Z 的顺序对照转换为一个字符,例如 101010 转换为 'a',而 363636 转换为 'A'。
- 将每行中的字符由左至右串接起来形成一个字符串,注意两个字符之间并不会安插任何的空格符。
- 输入中的 2L−12L - 12L−1 行每行会有一个字符串,依序代表编码后由上至下的这 2L−12L - 12L−1 个字符串。
接下来的一行有一个整数 QQQ 代表接下来有几组询问。 接下来的 QQQ 行每行有三个正整数 xxx, yyy 及 lll,代表一组询问 <x,y,l><x, y, l><x,y,l>。
下图为范例测试资料中的六边形网格,格子内显示的数字代表颜色,而非坐标:
- 1≤L≤2501 \le L \le 2501≤L≤250
- 代表六边形网格的字符串中只会有 0-9a-zA-Z 这些字符。
- 0≤Q≤3×1050 \le Q \le 3 \times 10^50≤Q≤3×105
- 1≤x≤4L−31 \le x \le 4L -31≤x≤4L−3
- 1≤y≤2L−11 \le y \le 2L - 11≤y≤2L−1
- 1≤l≤L1 \le l \le L1≤l≤L
- (x,y)(x, y)(x,y) 一定是给定的六边形网格中合法的格子点。
- <x,y,l><x, y, l><x,y,l> 询问的子六边形网格一定完整的位于主网格中。
- 1≤T≤151 \le T \le 151≤T≤15
- 至多 111 笔测试资料中的 L>50L > 50L>50
- 至多 111 笔测试资料中的 Q>1000Q > 1000Q>1000
Output
对于每一笔测试资料,对于每一个询问,请依序各自在一行内输出一个整数,代表此询问的答案。 两笔测试资料间请不要输出多余的空白行。
Sample Input
1 3 012 3456 789ab cdef ghi 10 1 3 1 1 3 2 1 3 3 9 3 1 7 3 1 3 3 1 3 3 2 5 3 1 5 3 2 2 2 2
Sample Output
1 7 19 1 1 1 7 1 7 7
1.
考虑坐标转换,主要是这6,7个六边形的 “锚点” 比较难计算。提供一种思路,考虑 锚点为(x,y) ,分别求出 其余点的 坐标,然后当我们需要 紧挨着 六个顶点的锚点坐标时, 只需要计算出相应的顶点坐标,然后利用他与 小六边形锚点的向量, 直接计算得到坐标。
2.
清楚自己的状态定义, 就是锚点的相对位置都是最左边的那一个,不要乱动。
HDU数据 不对,交什么 都TLE, 能叫的时候帮忙留个言。
#include<cstdio>
#include<cstring>
#include<ctype.h>
#include<algorithm>
using namespace std;
typedef long long LL;
#define rep(i,a,b) for(int i=a;i<b;i++)
//IO挂
//begin
inline void read(int &x){
x=0;
static int p;p=1;
static char c;c=getchar();
while(!isdigit(c)){if(c=='-')p=-1;c=getchar();}
while(isdigit(c)) {x=(x<<1)+(x<<3)+(c-48);c=getchar();}
x*=p;
}
inline void print(int x){
static int cnt;
static int a[20];
cnt=0;
do{
a[++cnt]=x%10;
x/=10;
}while(x);
for(int i=cnt;i>=1;i--)putchar(a[i]+'0');
puts("");
}
//end
LL dp[510][1200][10];
char str[300];
LL bit[63];
inline LL color(char ch){
LL ans=1;
if(ch>='0'&&ch<='9') ans=ch-'0';
else if(ch>='a'&&ch<='z') ans=ch-'a'+10;
else ans=ch-'A'+36;
return bit[ans];
}
int Log[300];
void get_pos(int id,int& x,int& y,int L,int Len){
if(id==1){
x=x-Len+1,y=y+Len-1;
x=x+L-1,y=y+1-L;
}
else if(id==2){
x=x-Len+1,y=y+3*Len-3;
x=x+L-1,y=y+3-3*L;
}
else if(id==3){
x=x,y=y;
}
else if(id==4){
x=x,y=y+2*Len-2;
x=x,y=y+2-2*L;
}
else if(id==5){
x=x,y=y+4*Len-2;
x=x,y=y+2-4*L;
}
else if(id==6){
x=x+Len-1,y=y+Len-1;
x=x+1-L,y=y+1-L;
}
else if(id==7){
x=x+Len-1,y=y+3*Len-3;
x=x+1-L, y=y+3-3*L;
}
}
int LEN[300];
LL col[10];
LL get_ans(int x,int y,int n){
int Len=LEN[n];
rep(i,0,7){
int xx=x,yy=y;
get_pos(i+1,xx,yy,Len/2,Len);
col[i]=dp[xx][yy][n-1];
}
LL ans=0;
rep(i,0,7)ans=ans|col[i];
return ans;
}
void RMQ(const int L){
int st,ed,len;
for(int i=1;i<=Log[L];i++){
int mov=LEN[i];
st=L-(mov-1),len=L+mov-1,ed=st+(len-1)*2;
for(int x=1+mov-1;x<=2*L-mov+1;x++){
for(int y=st;y<=ed;y+=2){
dp[x][y][i]=get_ans(x,y,i);
}
if(x<L)st--,ed++;
else st++,ed--;
}
}
}
int query(int x,int y,int L){
LL ans=0;
int len=LEN[Log[L]];
for(int i=0;i<7;i++){
int xx=x,yy=y;
get_pos(i+1,xx,yy,len,L);
//printf("&&&&&&&&&&***(%d,%d) len:%d L:%d\n",p.x,p.y,len,L);
ans|=dp[xx][yy][Log[L]];
}
int cnt=0;
//printf("(%d,%d,%d) %d\n",x,y,L,Log[L]);
//cnt=__builtin_popcountll(ans);
while(ans){
ans = ans & (ans-1);
cnt++;
}
return cnt;
}
int main(){
rep(i,0,63) bit[i]=(1LL<<i);
rep(i,2,300)Log[i]=Log[i>>1]+1;
rep(i,1,300)LEN[Log[i]]=(1<<Log[i]);
int T;
while(scanf("%d",&T)==1){
while(T--){
int L;
read(L);
int len=L,st=1+L-1;
rep(i,1,2*L){
scanf(" %s",&str);
int y=st;
rep(j,0,len){
dp[i][y][0]=color(str[j]);
y+=2;
}
if(i<L)len++,st--;
else len--,st++;
}
RMQ(L);
int m;
read(m);
printf("-1\n");
rep(i,0,m){
int x,y,L;
read(x);read(y);read(L);
int ans=query(y,x,L);
print(ans);
}
}
}
return 0;
}