字符串处理

Turbo Pascal提供了八个标准函数和标准过程,利用它们可以灵活解决字符串解题中的一些问题。 
length(st:string):byte 函数,返回st串的长度,既串中字符的个数。函数值字节型byte 0~255。
pos(sub,st:string):byte 函数,在st串中找子串sub,找到后返回值为sub在st中的位置,若没找到,函数值为0。                      
str(value,st) 函数,将整数或实数value转换成数字字符串st 。 
val(st, value,code) 过程,将字符串st 转换成数value, code返回st中第一个非法字符的位置,未有错,code为0。 
copy(st,pos,num) 函数, 在字符串st中从第pos个字符开始顺序截取num个字符。若pos大于st的长度,则返回空串。 
insert(sub,st,pos) 过程,在字符串st的第pos个字符位置处插入子串sub。 
delete(st,pos,num) 过程,删除st中第pos个字符开始的num个字符。 
upcase(st):st 函数,将字母ch转换成大写字母。

POJ 1008(模拟)

最后一天特判

Program P1008;
var
   n,i,j1,j2,j,day,month,year:longint;
   daytotal,tday,tmonth,tyear:longint;
   s,s1:string;
   mon:array[1..19] of string=('pop','no','zip','zotz','tzec','xul','yoxkin','mol','chen','yax','zac','ceh','mac','kankin','muan', 'pax', 'koyab', 'cumhu','uayet');
   tmon:array[1..20] of string=('imix', 'ik', 'akbal','kan','chicchan','cimi','manik','lamat','muluk','ok','chuen','eb','ben','ix','mem','cib','caban','eznab','canac','ahau');
begin
   readln(n);
   writeln(n);
   for i:=1 to n do
   begin
      readln(s);
      j1:=1;
      while (s[j1]<>'.') do inc(j1);
      s1:=copy(s,1,j1-1);
      val(s1,day);
      j2:=length(s);
      while (s[j2]<>' ') do dec(j2);
      s1:=copy(s,j2+1,5);
      val(s1,year);
      inc(j1);
      s1:=copy(s,j1+1,j2-j1-1);
      for j:=1 to 19 do
         if s1=mon[j] then
         begin
            month:=j;
            break;
         end;
      daytotal:=year*365+day+1+(month-1)*20;
      tyear:=(daytotal-1) div 260;
      tday:=(daytotal mod 13);
      if tday=0  then tday:=13;
      tmonth:=(daytotal mod 20);
      if tmonth=0 then tmonth:=20;
      writeln(tday,' ',tmon[tmonth],' ',tyear);
   end;

end.

POJ 1836(双向LIS)

双向LIS……居然数组又开小了……

Program P1836;
var
   n,i,j,ans:longint;
   a:array[1..1000] of double;
   ll,lr:array[1..1000] of longint;
function min(a,b:longint):longint;
begin
   if a<b then exit(a) else exit(b);
end;
begin
   fillchar(ll,sizeof(ll),0);
   fillchar(lr,sizeof(lr),0);

   read(n);
   for i:=1 to n do read(a[i]);
   ll[1]:=1;
   for i:=2 to n do
   begin
      for j:=1 to i-1 do
         if a[j]<a[i] then if (ll[j]>=ll[i]) then
            ll[i]:=ll[j]+1;
      if ll[i]=0 then inc(ll[i]);
   end;
   lr[n]:=1;
   for i:=n-1 downto 1 do
   begin
      for j:=i+1 to n do
         if a[j]<a[i] then if (lr[j]>=lr[i]) then
            lr[i]:=lr[j]+1;
      if lr[i]=0 then inc(lr[i]);
   end;
   ans:=n;
   for i:=1 to n do
      ans:=min(ans,n-(ll[i]+lr[i]-1));
   for i:=1 to n do
      for j:=i+1 to n do
         ans:=min(ans,n-(ll[i]+lr[j]));
   writeln(ans);
end.

POJ 1837(Dp水题)

这题居然不用高精度就能过……测试数据好弱

Program P1837;
var
   c,g,i,j,k,p:longint;
   li,w:array[1..20] of longint;
   f:array[1..20,-7500..7500] of longint;
begin
   fillchar(f,sizeof(f),0);
   read(c,g);
   for i:=1 to c do read(li[i]);
   for i:=1 to g do read(w[i]);
   for i:=1 to c do f[1,li[i]*w[1]]:=1;
   for i:=2 to g do
      for j:=1 to c do
      begin
         p:=li[j]*w[i];
         if p<0 then
         begin
            for k:=-7500 to 7500+p do
               if f[i-1,k-p]>0 then
                  inc(f[i,k],f[i-1,k-p])
         end
         else
         begin
            for k:=-7500+p to 7500 do
               if f[i-1,k-p]>0 then
                  inc(f[i,k],f[i-1,k-p]);
         end;
      end;
   writeln(f[g,0]);
end.

POJ 1007(求逆序对数)

求逆序对数,2关键字排序

Program P1007;
var
   n,m,i,j,k,l,p:longint;
   a:array[1..200] of string;
   s:string;
   b,num:array[1..200] of longint;
function h(s:string):longint;
var
   i,j,a,c,g,t:longint;
begin
   a:=0;
   c:=0;
   g:=0;
   t:=0;
   h:=0;
   for i:=length(s) downto 1 do
   begin
      if s[i]='A' then inc(a);
      if s[i]='C' then
      begin
         inc(c);
         inc(h,a);
      end;
      if s[i]='G' then
      begin
         inc(g);
         inc(h,a+c);
      end;
      if s[i]='T' then
      begin
         inc(t);
         inc(h,a+c+g);
      end;
   end;
end;
procedure qsort(l,r:longint);
var
   i,j,m,p:longint;
   s2:string;
begin
   i:=l;
   j:=r;
   m:=b[(l+r) div 2];
   repeat
      while b[i]<m do inc(i);
      while b[j]>m do dec(j);
      if i<=j then
      begin
         p:=b[i];
         b[i]:=b[j];
         b[j]:=p;
         p:=num[i];
         num[i]:=num[j];
         num[j]:=p;
{         s2:=a[i];
         a[i]:=a[j];
         a[j]:=s2;
}        inc(i);
         dec(j);
      end;
   until i>j;
   if l<j then qsort(l,j);
   if i<r then qsort(i,r);
end;
begin
   readln(n,m);
   for i:=1 to m do
   begin
      readln(a[i]);
      b[i]:=h(a[i]);
      num[i]:=i;
   end;
   qsort(1,m);
   i:=1;
   while (i<m) do
   begin
      if b[i]<b[i+1] then inc(i)
      else
      begin
         for j:=i+1 to m do if b[j]<>b[i] then break;
         if (b[i]<>b[m]) then dec(J);
         for k:=i to j-1 do
            for l:=k+1 to j do
               if num[k]>num[l] then
               begin
                  p:=num[k];
                  num[k]:=num[l];
                  num[l]:=p;
 {                 s:=a[k];
                  a[k]:=a[l];
                  a[l]:=s;
  }             end;
         i:=j+1;
      end;
   end;
   for i:=1 to m do writeln(a[num[i]]);
end.

POJ 1006(中国剩余定理)

中国剩余定理

若一个数除m1余p1,除m2余p2……,除mn余pn (m1,m2……,mn互质)

则求 k1使k1=m2*……*mn的倍数且除m1余1

……

则这个数为(k1*p1+k2*p2+……kn*pn) mod (m1*m2*……*mn)

Program P1005;
var
   a,b,c,d,i,a1,a2,a3,ans:longint;
begin
   i:=1;
   a1:=28*33;
   a2:=23*33;
   a3:=23*28;
   while (a1 mod 23<>1) do inc(a1,28*33);
   while (a2 mod 28<>1) do inc(a2,23*33);
   while (a3 mod 33<>1) do inc(a3,23*28);

   while (true) do
   begin
      read(a,b,c,d);
      if (a=-1) and (b=-1) and (c=-1) and (d=-1) then break;
      ans:=(a1*a+a2*b+a3*c+21252-d) mod 21252;
      if ans=0 then ans:=21252;
      writeln('Case ',i,': the next triple peak occurs in ',ans,' days.');
      inc(i);
   end;
end.

POJ 1005(向后去整)

小数处理……

Program P1005;
const
   pi=3.1415926;
Var
   t,i,j:longint;
   x,y,s:double;
begin
   read(t);
   for i:=1 to t do
   begin
      read(x,y);
      s:=sqrt(x*x+y*y);
      s:=s*s*pi/2;
      s:=s/50;
      if trunc(s)<s then s:=trunc(s)+1
      else s:=trunc(s);
      writeln('Property ',i,': This property will begin eroding in year ',s:0:0,'.');

   end;
   writeln('END OF OUTPUT.');
end.

POJ 1014(背包问题)

限制背包

Program P1014;
const
   maxv=120000;
   n=6;
var
   a:array[1..6] of longint;
   i,j,k,l,v:longint;
   f:array[0..maxv] of boolean;
function max(a,b:longint):longint;
begin
   if a>b then exit(a) else exit(b);
end;
procedure CompletePack(cost:longint);
var
   i:longint;
begin
   for i:=cost to v do
      f[i]:=f[i] or f[i-cost];
end;
procedure ZeroOnePack(cost:longint);
var
   i:longint;
begin
   if cost=0 then exit;
   for i:=v downto cost do
   begin
      f[i]:=f[i] or f[i-cost];
   end;
end;

procedure main;
var
   i,j,k,l,sum,p:longint;
begin
   v:=v div 2;
   for i:=1 to n do
   begin
      if i*a[i]>=v then
      begin
         CompletePack(i);
         continue;
      end;
      sum:=1;
      k:=0;
      while (a[i]-sum+1>0) do begin inc(k); sum:=sum*2; end;
      dec(k);
      sum:=1;
      for j:=0 to k-1 do
      begin
         ZeroOnePack(sum*i);
         sum:=sum*2;
      end;
      ZeroOnePack((a[i]-sum+1)*i);
      if f[v] then
      begin
         writeln('Can be divided.');
         exit;
      end;
   end;
   if not(f[v]) then writeln('Can''t be divided.')
   else writeln('Can be divided.')
end;
begin
   for i:=1 to n do read(a[i]);
   j:=1;
   while (a[1]+a[2]+a[3]+a[4]+a[5]+a[6]<>0) do
   begin
      writeln('Collection #',j,':');

      fillchar(f,sizeof(f),false);
      f[0]:=true;
      v:=0;
      for i:=1 to n do inc(v,i*a[i]);
      if (v mod 2=1) then writeln('Can''t be divided.')
      else
      begin
         main;
      end;

      writeln;
      for i:=1 to n do read(a[i]);
      inc(j);
   end;
end.

POJ 2140(数学问题)

问n=a+a+1+a+2+...+a+k 的情况总数

n=(k+1)*a+(k+1)*k/2

 =(k+1)(a+k/2)

n为整数,k+1为整数,(a+k/2)为整数,k为偶数,k+1为奇数

当n和k+1确定时,a为定值

故解为n的奇因子个数

Program P2140;
var
   i,n,ans:longint;
begin
   ans:=0;
   read(n);
   i:=1;
   while (i<=n) do
   begin
      if (n mod i=0) then inc(ans);
      inc(i,2);
   end;
   writeln(ans);
end.