【细心题】数三角
数三角
【问题描述】
这是一个数三角的游戏。长度为 1 或 SQRT(2)的小木棍放在一个网格上。如图所示,有
水平的,垂直的或对角的。对角放置的木棍可以交叉。
将木棍随意地放在网格上得到的图案可能不含三角形,
也可能含一个或多个三角形。
如
下图所示,
(a),(b),(c),(d)和(e)分别含有 2,5,12,0,0 个三角形。
你的任务是写一个程序数出一个图案中的三
角形个数。
【输入】
输入文件 count.in 包括 N+1 行:
先输入图案中木棍的个数 N。下面输入这 N 根木棍的位置,用两个网格坐标表示,这
两个坐标分别为木棍两端的位置。网格大小不超过 1010,因此网格左下和右上的坐标分别
为(0,0)和(9,9)。
【输出】
输入文件 count.out 包括 1 行:
三角形的个数。
【输入输出样例】
count.in
3 1
0001
0010
0110
count.out
1
program count; { Col:合肥一中冲刺 NOIP2012 训练(二) Prob:count Date:2012/10/09 BY:HT } {4 3 2 \ | / \ | / 5----*---- 1 / | \ / | \ 6 7 8 } uses math; Const dx:array[1..8] of longint=(1,1,0,-1,-1,-1,0,1); dy:array[1..8] of longint=(0,1,1,1,0,-1,-1,-1); op:array[1..8] of longint=(5,6,7,8,1,2,3,4); Var a:array[-2..20,-2..20,0..8] of boolean; f:array[-2..20,-2..20,0..8] of longint; n,i,j,k,x1,y1,x2,y2,ans:longint; Procedure fopen; begin assign(input,'count.in'); assign(output,'count.out'); reset(input); rewrite(output); end; Procedure fclose; begin close(input); close(output); end; begin fopen; fillchar(a,sizeof(a),false); readln(n); for i:=1 to n do begin readln(x1,y1,x2,y2); for j:=1 to 8 do if (x2=x1+dx[j]) and (y2=y1+dy[j]) then begin a[x1,y1,j]:=true; a[x2,y2,op[j]]:=true; end; end; for i:=0 to 9 do for j:=0 to 9 do for k:=5 to 8 do if a[i,j,k] then f[i,j,k]:=f[i+dx[k],j+dy[k],k]+1; for i:=0 to 9 do for j:=0 to 9 do for k:=1 to 4 do if a[i,j,k] then f[i,j,k]:=f[i+dx[k],j+dy[k],k]+1; ans:=0; { for i:=0 to 9 do for j:=0 to 9 do begin writeln('(',i,',',j,') :'); for k:=1 to 8 do writeln(f[i,j,k]); end; } //point(x,y) for i:=0 to 9 do for j:=0 to 9 do begin //case 1 |_ for k:=1 to min(f[i,j,1],f[i,j,3]) do if f[i+dx[1]*k,j+dy[1]*k,4]>=k then inc(ans); //case 2 \/ for k:=1 to min(f[i,j,2],f[i,j,4]) do if f[i+dx[2]*k,j+dy[2]*k,5]>=k then inc(ans); //case 3 _| for k:=1 to min(f[i,j,3],f[i,j,5]) do if f[i+dx[3]*k,j+dy[3]*k,6]>=k then inc(ans); //case 4 \ // / for k:=1 to min(f[i,j,4],f[i,j,6]) do if f[i+dx[4]*k,j+dy[4]*k,7]>=k then inc(ans); //case 5 -- // | for k:=1 to min(f[i,j,5],f[i,j,7]) do if f[i+dx[5]*k,j+dy[5]*k,8]>=k then inc(ans); //case 6 /\ for k:=1 to min(f[i,j,6],f[i,j,8]) do if f[i+dx[6]*k,j+dy[6]*k,1]>=k then inc(ans); //case 7 |- for k:=1 to min(f[i,j,7],f[i,j,1]) do if f[i+dx[7]*k,j+dy[7]*k,2]>=k then inc(ans); //case 8 / // \ for k:=1 to min(f[i,j,8],f[i,j,2]) do if f[i+dx[8]*k,j+dy[8]*k,3]>=k then inc(ans); end; //points in squere for i:=0 to 8 do for j:=0 to 8 do begin for k:=1 to min(f[i,j,2],f[i,j+1,8]) do if f[i+dx[2]*k,j+dy[2]*k,7]>=k then inc(ans); for k:=1 to min(f[i,j,2],f[i+1,j,4]) do if f[i+dx[2]*k,j+dy[2]*k,5]>=k then inc(ans); for k:=1 to min(f[i+1,j+1,6],f[i+1,j,4]) do if f[i+1+dx[4]*k,j+dy[4]*k,7]>=k then inc(ans); for k:=1 to min(f[i+1,j+1,6],f[i,j+1,8]) do if f[i+1+dx[6]*k,j+1+dy[6]*k,1]>=k then inc(ans); end; writeln(ans); fclose; end.