2 条题解
- 
  0flysky LV 8 @ 2014-10-29 18:12:38 program exam; 
 var sum,map:array[0..1001,0..2001] of longint;
 spot:array[0..1000001] of int64;
 g:array[0..1001,0..1001] of char;
 n,m,t,r,i,j,tot,vi,vj:longint;ans:int64;
 procedure initfile;
 begin
 assign(input,'b.in');
 reset(input);
 assign(output,'b.out');
 rewrite(output);
 end;
 procedure closefile;
 begin
 close(input);
 close(output);
 end;
 procedure qs(l,r:longint);
 var i,j:longint;x,tmp:int64;
 begin
 i:=l;j:=r;
 x:=spot[(i+j) shr 1];
 repeat
 while spot[i]>x do inc(i);
 while spot[j]<x do dec(j);
 if i<=j then
 begin
 tmp:=spot[i];spot[i]:=spot[j];spot[j]:=tmp;
 inc(i);dec(j);
 end;
 until i>j;
 if i<r then qs(i,r);
 if l<j then qs(l,j);
 end;
 function min(x,y:longint):longint;
 begin if x<y then exit(x) else exit(y);end;
 function max(x,y:longint):longint;
 begin if x>y then exit(x) else exit(y);end;
 procedure initdata;
 var i,j,k,h:longint;
 begin
 readln(n,m,t,r);
 fillchar(sum,sizeof(sum),0);
 for i:=1 to n do
 begin
 for j:=1 to m do
 begin
 vi:=i-j+m;vj:=i+j-1;
 read(g[i,j]);
 if g[i,j]='O' then
 map[vi,vj]:=1;
 end;
 readln;
 end;
 for i:=1 to n+m-1 do
 for j:=1 to n+m-1 do
 begin
 sum[i,j]:=sum[i-1,j]+sum[i,j-1]-sum[i-1,j-1]+map[i,j];
 end;
 for i:=1 to n do
 for j:=1 to m do
 if g[i,j]='*' then
 begin
 inc(tot);
 vi:=i-j+m;vj:=i+j-1;spot[tot]:=sum[min(vi+r,n+m-1),min(vj+r,n+m-1)]- 
 sum[min(vi+r,n+m-1),max(vj-r,1)-1]-
 sum[max(vi-r,1)-1,min(vj+r,n+m-1)]+
 sum[max(vi-r,1)-1,max(vj-r,1)-1];end; 
 qs(1,tot);
 end;
 begininitdata; 
 ans:=0;
 for i:=1 to t do
 begin
 ans:=ans+spot[i];
 end;
 writeln(ans);end. 
- 
  0@ 2014-09-08 01:01:03(语文超渣求轻喷………………T_T 我们发现,一个塔的攻击范围是一个斜着的正方形。 
 换句话说,我们考虑左右对角线,我们依照这两种对角线把每个点重新标号为。 (i', j') 表示一个坐标为 (i, j) 的点在第 i' 条左对角线,在第 j' 条右对角线上。
 看过八皇后问题后就会明白了。
 那么标号方法就是,对于一个原坐标为 (i, j) 的点: i' = i-j+m, j' = i+j-1 (1 <= i <= n, 1 <= j <= m) 。
 一个塔在新坐标 (x', y') 能够攻击的到新坐标 (i', j') 满足以下条件的所有点: max(x'-R, 1) <= i' <= min(x'+R, n), max(y'-R, 1) <= j' <= min(y'+R, m)这个可以用二维前缀和轻松地算出。 
 (二维前缀和:sum[i][j]表示矩阵A[n][m]的子矩阵A[1...i][1...j]的和,递推式sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+A[i][j]
 询问A[x0...x1][y0...y1]的和就是sum[x1][y1]-sum[x0-1][y1]-sum[x1][y0-1]+sum[x0-1][y0-1])
 时间复杂度 O(nm) 。Falsyta 
- 1
信息
- ID
- 1877
- 难度
- 8
- 分类
- (无)
- 标签
- (无)
- 递交数
- 281
- 已通过
- 33
- 通过率
- 12%
- 被复制
- 3
- 上传者