Hướng dẫn giải của Tam giác vuông


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này

Code mẫu của flashmt

const fi='';
      fo='';
      maxn=1505;
      delta:real=10000000000;
type ar=array[1..maxn] of longint;
     arr=array[1..maxn] of real;
var n,re,m,mm:longint;
    x,y,d,dd:ar;
    a,aa:arr;

procedure rf;
var i:longint;
begin
     readln(n);
     for i:=1 to n do readln(x[i],y[i]);
end;

procedure rotatecalc(i:longint);
var j,t,u,dem:longint;
begin
     dem:=0;
     for j:=1 to n do
     begin
          if j=i then continue;
          dem:=dem+1;
          t:=x[j]-x[i]; u:=y[j]-y[i];
          if t=0 then a[dem]:=delta
          else a[dem]:=u/t;
          if u=0 then aa[dem]:=delta
          else aa[dem]:=-t/u;
     end;
end;

procedure sort(var a:arr;l,r:longint);
var i,j:longint; x,t:real;
begin
     i:=l; j:=r; x:=a[(i+j) shr 1];
     repeat
           while a[i]<x do i:=i+1;
           while a[j]>x do j:=j-1;
           if i<=j then
           begin
                t:=a[i]; a[i]:=a[j]; a[j]:=t;
                i:=i+1; j:=j-1;
           end;
     until i>j;
     if i<r then sort(a,i,r);
     if l<j then sort(a,l,j);
end;

procedure edit(var a:arr;var d:ar;var m:longint);
var i:longint;
begin
     m:=1; d[1]:=1;
     for i:=2 to n do
         if a[i]<>a[m] then
         begin
              m:=m+1; a[m]:=a[i]; d[m]:=1;
         end
         else d[m]:=d[m]+1;
end;

procedure pr;
var i,j,k:longint;
begin
     re:=0;
     for i:=1 to n do
     begin
          rotatecalc(i);
          sort(a,1,n-1);
          sort(aa,1,n-1);
          edit(a,d,m);
          edit(aa,dd,mm);
          j:=1; k:=1;
          while (j<=m) and (k<=mm) do
          begin
               if a[j]<aa[k] then j:=j+1
               else
               begin
                    if a[j]=aa[k] then re:=re+d[j]*dd[k];
                    k:=k+1;
               end;
          end;
     end;
end;

procedure wf;
begin
     writeln(re shr 1);
end;

begin
     assign(input,fi); reset(input);
     assign(output,fo); rewrite(output);
     rf;
     pr;
     wf;
     close(input); close(output);
end.

Code mẫu của ladpro98

#include <iostream>
#include <cstdio>
#include <algorithm>
#define ii pair<int, int>
#define X first
#define Y second
const int N = 1555;
const long double eps = 1e8;
using namespace std;
ii v[N];
ii a[N];
int n, top;

int gcd(int a, int b) {
    while (b) a %= b, swap(a, b); return a;
}

void refine(ii &v) {
    int g = gcd(v.X, v.Y);
    v.X /= g; v.Y /= g;
    if (v.X < 0) {
        v.X = -v.X; v.Y = -v.Y;
    }
}

int main() {
    ios :: sync_with_stdio(0);
    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> a[i].X >> a[i].Y;
    int res = 0;
    ii t;
    for(int i = 1; i <= n; i++) {
        top = 0;
        for(int j = 1; j <= n; j++)
        if (i != j)
            v[top++] = ii(a[i].X - a[j].X, a[i].Y - a[j].Y);
        for(int j = 0; j < top; j++) refine(v[j]);
        sort(v, v + top);
        for(int j = 0; j < top; j++) {
            t = ii(v[j].Y, -v[j].X);
            if (t.X < 0) {t.X = -t.X; t.Y = -t.Y;}
            res += upper_bound(v + j + 1, v + top, t) -
                   lower_bound(v + j + 1, v + top, t);
        }
    }
    cout << res;
    return 0;
}

Code mẫu của RR

//Written by Nguyen Thanh Trung
//Finally I am able to solve this problem
{$R+,Q+,N+}
{$Mode objFPC}
uses math;
const
  FINP='';
  FOUT='';
  MAXN=1511;
  eps=1e-14;
type
  point=record x,y:double; end;
var
  f1,f2:text;
  n:longint;
  a:array[1..MAXN] of point;
  goc:array[1..MAXN] of double;
  count:array[1..MAXN] of longint;
procedure openF;
begin
  assign(f1,FINP); reset(f1);
  assign(f2,FOUT); rewrite(f2);
end;
procedure closeF;
begin
  close(f1);
  close(f2);
end;
procedure inp; inline;
var
  i:longint;
begin
  read(f1,n);
  for i:=1 to n do
    with a[i] do read(f1,x,y);
end;
procedure swapd(var a,b:double); inline;
var temp:double; begin temp:=a; a:=b; b:=temp; end;
var mid:double;
procedure sort(l,r:longint); inline;
var
  i,j:longint;
begin
  i:=l; j:=r; mid:=goc[l+random(r-l+1)];
  repeat
    while goc[i]<mid do inc(i);
    while goc[j]>mid do dec(j);
    if i<=j then
      begin
        swapd(goc[i],goc[j]);
        inc(i); dec(j);
      end;
  until i>j;
  if i<r then sort(i,r);
  if l<j then sort(l,j);
end;
procedure solve;
var
  i,ii,k,now,prev:longint;
  countx,county,sl,kq:longint;
begin
  kq:=0;
  for i:=1 to n do
    begin
      countx:=0; county:=0; sl:=0;
      for ii:=1 to n do
      if ii<>i then
        if a[i].x=a[ii].x then inc(countx)
        else if a[i].y=a[ii].y then inc(county)
        else
          begin
            inc(sl);
            goc[sl]:=arctan((a[ii].y-a[i].y)/(a[ii].x-a[i].x));
          end;
        kq+=countx*county;
        if sl<2 then continue;
        sort(1,sl);
        k:=1; count[1]:=1;
        for ii:=2 to sl do
          if goc[ii]>goc[k]+eps then
            begin
              inc(k);
              goc[k]:=goc[ii];
              count[k]:=1;
            end
          else count[k]+=1;
        sl:=k;
        prev:=0;
        for now:=1 to sl do
          begin
            while (prev<sl) and (goc[prev+1]<goc[now]-pi/2+eps) do inc(prev);
            if (prev>0) and (abs(goc[now]-goc[prev]-pi/2)<eps) then kq+=count[now]*count[prev];
          end;
    end;
  writeln(f2,kq);
end;
begin
  openF;
  inp;
  solve;
  closeF;
end.

Code mẫu của hieult

#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<cassert>
#include<ctime>
#include<algorithm>
#include<iterator>
#include<iostream>
#include<cctype>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<list>
//#include<conio.h>
#define maxn 1502
#define oo 1111111111
#define base 100000000
#define TR(c, it) for(typeof((c).begin()) it=(c).begin(); it!=(c).end(); it++)
long double const PI= acos((long double)(-1));
long double const ep = 0.000000000001;
using namespace std;

typedef pair<int, int> II;
typedef vector<int> VI;
typedef vector<II> VII;
typedef vector<VI> VVI;
typedef vector<VII> VVII;
typedef long double ld;

void OPEN(){
    freopen("A.in", "r", stdin);
    freopen("A.out", "w", stdout); 
}

struct diem{
     long long x,y;
};

struct vec_tor{
     long long x,y;
     long double goc;
     vec_tor(){};
     vec_tor(diem D1,diem D2){
           x = D2.x-D1.x;
           y = D2.y-D1.y;
           if(y<0){
                x = -x;
                y = -y;
           }
           if(y==0) x>0?x:-x;
           goc = atan2((ld)y,(ld)x);
     }
     bool operator <(vec_tor T)const{
           return (x*T.y>y*T.x);// && x * T.x >= 0 && y * T.y >= 0);
     }
     bool operator ==(vec_tor T)const{
           return ( x*T.y == y*T.x && x * T.x >= 0 && y * T.y >= 0);
     }
     int vuonggoc(vec_tor T) const{
           if (x*T.x==-y*T.y) return 0;
           if(x * T.x + y * T.y > 0) return 1;
           return -1;
     }
};

diem A[1511];
vec_tor  V[3011];
long long KQ = 0;
int n;

int main(){
     //OPEN();
     scanf("%d",&n);
     for(int i = 0;i<n;i++)
           scanf("%lld %lld",&A[i].x,&A[i].y);
     for(int i = 0;i<n;i++){ 
           int t = 0; 
           for(int j = 0;j<n;j++){
                 if(i!=j)
                      V[t++] = vec_tor(A[i],A[j]);
           }
           sort(V,V+t);
           int u=0,run = 0;
           for(int j = 0;j<t;j++){
                 if(j>0 && V[j]==V[j-1]){
                      KQ+=run;
                      continue;
                 } 
                 while(V[j].vuonggoc(V[u]) == 1 && u<t) u++;
                 run = 0;
                 while(V[j].vuonggoc(V[u]) == 0 && u<t){                 
                      u++;
                      run++;
                      KQ++;
                 }
           } 
     }
     printf("%lld",KQ);
     //getch();
}

Code mẫu của ll931110

{$inline on}
{$N+}
program PRAVO;
const
  input  = '';
  output = '';
  maxn = 1500;
  eps = 1e-13;
var
  a,b,t: array[1..maxn] of longint;
  q,s: array[1..maxn] of extended;
  nb,cc: longint;
  n: longint;
  time: longint;
  res: longint;

procedure init;inline;
var
  f: text;
  i: longint;
begin
  assign(f, input);
    reset(f);

  readln(f, n);
  for i := 1 to n do readln(f, a[i], b[i]);

  close(f);
end;

procedure sort(l,h: longint);inline;
var
  i,j: longint;
  p,tmp: extended;
begin
  if l >= h then exit;
  i := l;  j := h;  p := s[random(h - l + 1) + l];

  repeat
    while s[i] < p do inc(i);
    while s[j] > p do dec(j);
    if i <= j then
      begin
        if i < j then
          begin
            tmp := s[i];  s[i] := s[j];  s[j] := tmp;
          end;
        inc(i);
        dec(j);
      end;
  until i > j;

  sort(l,j);  sort(i,h);
end;

procedure press;inline;
var
  i: longint;
begin
  nb := 0;
  if cc = 0 then exit;

  inc(nb);
  q[1] := s[1];  t[1] := 1;

  for i := 2 to cc do
    if s[i] > s[i - 1] then
      begin
        inc(nb);
        q[nb] := s[i];
        t[nb] := 1;
      end
    else inc(t[nb]);
end;

function equ(x,y: extended): boolean;inline;
begin
  equ := abs(x - y) < eps;
end;

function find(i: longint): longint;inline;
var
  inf,sup,med: longint;
  x: extended;
begin
  inf := i + 1;  sup := nb;
  x := -1/q[i];
  repeat
    med := (inf + sup) div 2;
    if equ(q[med],x) then exit(t[med])
    else if q[med] > x then sup := med - 1
    else inf := med + 1;
  until inf > sup;

  find := 0;
end;

procedure calc(x: longint);inline;
var
  i,n0,ninf: longint;
begin
  cc := 0;
  n0 := 0;
  ninf := 0;

  for i := 1 to n do if i <> x then
    if b[i] = b[x] then inc(ninf)
    else if a[i] = a[x] then inc(n0)
    else
      begin
        inc(cc);
        s[cc] := (b[i] - b[x]) / (a[i] - a[x]);
      end;

  if cc = 0 then exit;
  sort(1,cc);
  press;

  for i := 1 to nb - 1 do
    res := res + t[i] * find(i);
  res := res + n0 * ninf;
end;

procedure solve;inline;
var
  i: longint;
begin
  res := 0;
  for i := 1 to n do calc(i);
end;

procedure printresult;inline;
var
  f: text;
begin
  assign(f, output);
    rewrite(f);
    writeln(f, res);
  close(f);
end;

begin
  init;
  solve;
  printresult;
end.

Code mẫu của khuc_tuan

const
Epsilon = 1E-12;
Max = 1500;
var
goc, x, y: array[1..Max] of extended;
Left, Right:array[1..Max] of extended;
key, result: extended;
m, n, c: longint;
procedure Read_Data;
var
i: longint;
begin
Read(n);
For i := 1 to n do
Read(x[i], y[i]);
end;
procedure Swap(i, j: longint);
var
temp: extended;
begin
temp := goc[i];
goc[i] := goc[j];
goc[j] := temp;
end;
procedure Sort(L, R: longint);
var
i, j: longint;
k: extended;
begin
If L >= R then Exit;
i := L;
j := R;
k := goc[(i+j) shr 1];
Repeat
While goc[i] < k do inc(i);
While goc[j] > k do dec(j);
if i <= j then
begin
If i < j then Swap(i, j);
inc(i);
dec(j);
end;
Until i > j;
Sort(L, j);
Sort(i, R);
end;
function theta(x1, y1, x2, y2: extended): extended;
var
t, dx, dy, ax, ay: extended;
begin
dx := x2 - x1; ax := abs(dx);
dy := y2 - y1; ay := abs(dy);
If (dx = 0) and (dy = 0) then t := 0 else t := dy/(ax + ay);
If dx < 0 then t := 2 - t
else
if dy < 0 then t := 4 + t;
theta := t * 90;
end;
procedure Calculate;
var
i: longint;
begin
For i := 2 to m do
If abs(Goc[i] - Goc[i-1]) < Epsilon then
Left[i] := Left[i-1];
For i := m-1 downto 1 do
If abs(Goc[i] - Goc[i+1]) < Epsilon then
Right[i] := Right[i+1];
end;
procedure Init(i: longint);
var
j: longint;
begin
m := 0;
For j := 1 to n do
If j <> i then
begin
m := m + 1;
Left[m] := m;
Right[m] := m;
Goc[m] := theta(x[i], y[i], x[j], y[j]);
end;
Sort(1, m);
Calculate;
end;
procedure Find_Key(i: longint);
begin
If abs(Goc[i] - 270) < Epsilon then
begin
key := 0;
Exit;
end;
If Goc[i] < 270 then
key := Goc[i] + 90
Else
key := Goc[i] - 270;
end;
procedure Binary_search;
var
L, R, mid: longint;
begin
c := 0;
L := 1;
R := m;
Repeat
mid := (L + R) shr 1;
If abs(Goc[mid] - key) < Epsilon then
begin
c := mid;
Break;
end
else
If Goc[mid] < key then L := mid + 1
else R := mid - 1;
Until L > R;
end;
procedure Solve;
var
i, j: longint;
begin
result := 0;
For i := 1 to n do
begin
Init(i);
For j := 1 to m do
begin
Find_key(j);
Binary_search;
If c > 0 then result := result + Right[c] - Left[c] + 1;
end;
end;
end;
procedure Write_answer;
begin
Writeln( result :0: 0);
end;
begin
Read_Data;
Solve;
Write_answer;
end.

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.