第二届『Citric杯』NOIP提高组模拟赛

一道防AK的好题

    不得不吐槽这个题目背景和算法。这就是一脑筋急转弯啊。

Code
program hard;
CONST FileName='hard';
var n,i,tot:longint;
    x,a,b,c,ans:array[1..500000] of int64;
    left,right:int64;
function  calc(a,b,c:int64):int64;
          var i:longint;
              t:int64;
          begin
          for i:=1 to n do
            begin
            t:=a*(i+1)*x[i]*x[i]+(b+1)*i*x[i]+c+i;
            write(t:5);
            if(t=0)then calc:=i;
            end;
          end;
BEGIN
readln(n);
for i:=1 to n do read(x[i]);
while not eof do
  begin
  inc(tot);
  readln(a[tot],b[tot],c[tot]);
  end;
ans[tot-1]:=-a[tot];
for i:=tot-1 downto 2 do
  begin
  left:=a[i]*(ans[i]+1)*x[ans[i]]*x[ans[i]]+(b[i]+1)*ans[i]*x[ans[i]]+c[i]+ans[i];
  right:=(ans[i]+1)*x[ans[i]]*x[ans[i]]+ans[i]*x[ans[i]]+1;
  ans[i-1]:=-left div right
  end;
for i:=1 to tot-1 do writeln(ans[i]);
END.

 天空中的繁星
    四十分做法得了70分,好开心。

Code
CONST dx:array[1..4] of longint=(1,-1,0,0);
      dy:array[1..4] of longint=(0,0,1,-1);
      maxn=500;
var Q:array[1..maxn*maxn,1..2] of longint;
    vis,A,map:array[0..maxn+1,0..maxn+1] of boolean;
    sum:array[0..maxn+1,0..maxn+1] of longint;
    n,m,p,i,j,k,l,ans:longint;
    s:ansistring;
procedure BFS(x,y:longint);
          var h,t,i,nx,ny:longint;
              isstar:boolean;
          begin
          h:=0;t:=1;
          Q[1][1]:=x;
          Q[1][2]:=y;
          vis[x][y]:=true;
          while h<t do
            begin
            inc(h);isstar:=true;
            for i:=1 to 4 do
              begin
              nx:=Q[h][1]+dx[i];
              ny:=Q[h][2]+dy[i];
              if(map[nx][ny])and(not vis[nx][ny]) then
                begin
                vis[nx][ny]:=true;inc(t);
                Q[t][1]:=nx;Q[t][2]:=ny;
                end
              else if not map[nx][ny]
                     then isstar:=false;
              end;
            if isstar then A[Q[h][1]][Q[h][2]]:=true;
            end;
          end;

BEGIN
readln(n,m,p);
for i:=1 to n do
  begin
  readln(s);
  for j:=1 to m do
    if s[j]='*'
      then map[i][j]:=true;
  end;
for i:=1 to n do
  for j:=1 to m do
    if(not vis[i][j])and(map[i][j])
      then BFS(i,j);
for i:=1 to n do
  for j:=1 to m do
    begin
    sum[i][j]:=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
    if A[i][j] then inc(sum[i][j]);
    for k:=1 to i-2 do
      for l:=1 to j-2 do
        if sum[i-1][j-1]-sum[i-1][l]-
           sum[k][j-1]+sum[k][l]>=p
           then inc(ans);
    end;
writeln(ans);
END.

    应该注意到,对于给定的上、下、右三个边界,左边界能否满足条件满足一个单调性,是可以二分的,如果继续优化发现右边界增大,最大的满足条件的左边界不会减小,通过左边界计算方案数。滑窗应该算是新知识。

Code
program star;
CONST dx:array[1..4] of longint=(1,-1,0,0);
      dy:array[1..4] of longint=(0,0,1,-1);
      FileName='star';
      maxn=500;
var Q:array[1..maxn*maxn,1..2] of longint;
    vis,A,map:array[0..maxn+1,0..maxn+1] of boolean;
    sum:array[0..maxn+1,0..maxn+1] of longint;
    n,m,p,i,j,k,r,mid,l:longint;
    s:ansistring;
    find:boolean;
    ans:int64;
function  calc(a,b,c,d:longint):longint;
begin calc:=sum[c][d]-sum[c][b-1]-sum[a-1][d]+sum[a-1][b-1];end;
procedure BFS(x,y:longint);
          var h,t,i,nx,ny:longint;
              isstar:boolean;
          begin
          h:=0;t:=1;
          Q[1][1]:=x;
          Q[1][2]:=y;
          vis[x][y]:=true;
          while h<t do
            begin
            inc(h);isstar:=true;
            for i:=1 to 4 do
              begin
              nx:=Q[h][1]+dx[i];
              ny:=Q[h][2]+dy[i];
              if(map[nx][ny])and(not vis[nx][ny]) then
                begin
                vis[nx][ny]:=true;inc(t);
                Q[t][1]:=nx;Q[t][2]:=ny;
                end
              else if not map[nx][ny]
                     then isstar:=false;
              end;
            if isstar then A[Q[h][1]][Q[h][2]]:=true;
            end;
          end;
BEGIN
Assign(input,FileName+'.in');
Assign(output,FileName+'.out');
Reset(input);Rewrite(output);
readln(n,m,p);
for i:=1 to n do
  begin
  readln(s);
  for j:=1 to m do
    if s[j]='*'
      then map[i][j]:=true;
  end;
for i:=1 to n do
  for j:=1 to m do
    if(not vis[i][j])and(map[i][j])
      then BFS(i,j);
for i:=1 to n do
  for j:=1 to m do
    begin
    sum[i][j]:=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
    if A[i][j] then inc(sum[i][j]);
    l:=1;
    end;
for i:=1 to n do
  for j:=i+2 to n do
    begin
    l:=0;//滑了个窗
    for k:=3 to m do
      begin
      while calc(i+1,l+2,j-1,k-1)>=p do inc(l);
      inc(ans,l);
      end;
    {
    二了个分
    for k:=3 to m do
      begin
      l:=0;r:=k;
      while l<r-1 do
        begin
        mid:=(l+r)>>1;
          if calc(i+1,mid+1,j-1,k-1)>=p
          then l:=mid
          else r:=mid;
        end;
      inc(ans,l);
      end;
    }
    end;
writeln(ans);
Close(input);Close(output);
END.

柠檬的密码

   考试没来得及交,按二十分写的暴力居然过了6个点。

Code
//写的乱七八糟。。。
program password;
var s,p:array[1..2000] of char;
    a,b,l,r,maxi,n,ans,ans2,temp,len,i,j:longint;
begin
readln(n);
for i:=1 to n do
  begin
  read(s[i]);
  p[n-i+1]:=s[i];
  end;
len:=0;
for i:=1 to n do
  begin
  temp:=0;
  for j:=1 to n do
    if(p[j]=s[i+j-1])and(i+j-1<n-j+1)
     then inc(temp)
     else break;
  if temp>len
    then begin
         len:=temp;
         maxi:=i;
         end;
  end;
ans:=len<<1;
l:=maxi+len-1;r:=n-len;
for i:=l to r do
  for j:=i+1 to r do
    begin
    len:=(j-i+1);temp:=0;
    if(len and 1)=1
       then begin
            a:=i-1+(len+1)>>1-1;
            b:=a+2;
            temp:=1;
            end
       else begin
            a:=i+-1+len>>1;
            b:=i+-1+a+1;
            end;
    while(l<=a)and(b<=r)and(s[a]=s[b])do
      begin
      inc(temp,2);
      dec(a);inc(b);
      end;
    if temp>ans2 then ans2:=temp;
    end;
inc(ans,ans2);
writeln(ans);  
end.

    全部拿暴力分,排到51名,显然发现第一题是个脑筋急转弯的人不多。手快点就好了,第三题交上就能rank24了,要坚定敢于写暴力的信心~~~~~

转载于:https://www.cnblogs.com/lijianlin1995/archive/2012/08/25/2657037.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值