寒假的第一天,终于有空再写题目了,专心备战了。本想拿usaco上的题目练手热身,结果被磕住了T T。
其实这是一道穷举题,一开始我在穷举a,b,但是怎么优化就是过不了Test 8,后来参照NOCOW上的解题弄了se和list两个数组,也算是终于通过了,这时候已经是Submission #7了。(啊,有两次是因为没开文件,一次是因为没打‘NONE’)
总之,祝寒假的OI学习顺利吧~All or Nothing, Now or Never!

program ariprog2;
var se:array[0..62600*2] of boolean;
    list:array[0..62600] of longint;
    a0,b0:array[0..10000] of longint;
    m,n,i,j,a,b,count,ans_count,temp:longint;
    flag,code:boolean;
procedure start;
var i,j:longint;
begin
  count:=0;
  for i:=0 to m do
    for j:=0 to m do
      begin
        if se[i*i+j*j]=false then
          begin
            se[i*i+j*j]:=true;
            inc(count);
            list[count]:=i*i+j*j;
          end;
      end;
end;
procedure pd(a,b:longint);
var i:integer;
    flag:boolean;
begin
  if a+(n-1)*b>m*m*2 then exit;
  flag:=true;
  for i:=1 to n-1 do
    if se[a+i*b]=false then
      begin
        flag:=false;
        break;
      end;
  if flag then
    begin
      inc(ans_count);
      a0[ans_count]:=a;
      b0[ans_count]:=b;
    end;
end;

begin
  assign(input,'ariprog.in');reset(input);
  assign(output,'ariprog.out');rewrite(output);
  readln(n);
  readln(m);
  start;
  for i:=1 to count-1 do
    for j:=i+1 to count do
      begin
        a:=list[i];
        if list[j]<a then a:=list[j];
        b:=abs(list[j]-list[i]);
        pd(a,b);
      end;
  if ans_count<>0 then
    begin
      for i:=1 to ans_count-1 do
        for j:=i+1 to ans_count do
          begin
            if (b0[i]>b0[j]) or ((b0[i]=b0[j])and(a0[i]>a0[j])) then
              begin
                temp:=b0[i];b0[i]:=b0[j];b0[j]:=temp;
                temp:=a0[i];a0[i]:=a0[j];a0[j]:=temp;
              end;
          end;
      for i:=1 to ans_count do
        writeln(a0[i],' ',b0[i]);
    end
  else
    writeln('NONE');
  close(input);close(output);
end.
ariprog2

Executing...
Test 1: TEST OK [0.000 secs, 720 KB]
Test 2: TEST OK [0.000 secs, 720 KB]
Test 3: TEST OK [0.000 secs, 720 KB]
Test 4: TEST OK [0.000 secs, 720 KB]
Test 5: TEST OK [0.022 secs, 720 KB]
Test 6: TEST OK [0.151 secs, 720 KB]
Test 7: TEST OK [1.717 secs, 720 KB]
Test 8: TEST OK [3.823 secs, 720 KB]
Test 9: TEST OK [3.834 secs, 720 KB]

All tests OK.

话说,过了的那个程序可以再优化的。
题目讲输出范围小于10000我就直接上O(N^2)排序了,用快排可以再省一点时间吧。

顺便把那个怎么也过不掉Test 8的程序也发上来好了,不能让自己白打这么久!!

program ariprog;
var se,cha:array[0..62600*2] of boolean;
    m,n,i,j,k,l,a,b,max,num_se:longint;
    flag,code:boolean;

procedure start;
var i,j:integer;
begin
  fillchar(se,sizeof(se),false);
  for i:=0 to m do
    for j:=0 to m do
      se[i*i+j*j]:=true;
  fillchar(cha,sizeof(cha),false);
  for i:=0 to m do
    for j:=0 to m do
      for k:=0 to i do
        for l:=0 to j do
          cha[i*i+j*j-k*k-l*l]:=true;
end;

begin
  assign(input,'ariprog.in');reset(input);
  assign(output,'ariprog.out');rewrite(output);
  readln(n);
  readln(m);
  max:=2*m*m;
  code:=false;
  start;
  for b:=1 to trunc(max/(n-1)) do
    if cha[b]=true then
    begin
      for a:=0 to 2*m*m do
        begin
          if a+(n-1)*b>max then break;
          if se[a]=true then
            begin
              i:=1;flag:=true;
              while i<=n-1 do
                begin
                  if se[a+i*b]=false then
                    begin
                      flag:=false;
                      break;
                    end;
                  inc(i);
                end;
              if flag then
                begin
                  code:=true;
                  writeln(a,' ',b);
                end;
            end;
        end;
    end;
  if not code then writeln('NONE');
  close(input);close(output);
end.
ariprog

 

 posted on 2014-01-10 11:01  Sky-Grey  阅读(155)  评论(0编辑  收藏  举报