RQ83 魔兽世界

2011年8月16日 00:25

虽然只是普通的BFS,但此题非常神奇!如果通过传送门到一个点,那么点不需要被标记掉。代码又长又乱,几行又删了,凑合看吧.

 

const
        dire:array[1..4,1..2]of integer=((1,0),(0,1),(0,-1),(-1,0));

type
        int=longint;
        rec=record
                x1,x2,y1,y2:int;
                step:boolean;
        end;
        rec2=record
                 x,y,step:int;
        end;

var
        i,j,k,xx,yy,n,m,min,head,tail:int;
        map:array[1..101,1..101] of char;
        hash:array[1..101,1..101] of boolean;
        bro:array['A'..'Z'] of rec;
        f:array[0..10000] of rec2;
        ch:char;
        can,add:boolean;

begin
        min:=$fffffff;
        head:=0;tail:=1;can:=false;
        readln(n,m);
        for i:=1 to n do
        begin
                for j:=1 to m do
                begin
                        read(map[i][j]);
                        if map[i,j]>='A' then
                        begin
                                if bro[map[i][j]].step=false then
                                begin
                                        bro[map[i][j]].x1:=i;
                                        bro[map[i][j]].y1:=j;
                                        bro[map[i][j]].step:=true;
                                end
                                 else
                                begin
                                        bro[map[i][j]].x2:=i;
                                        bro[map[i][j]].y2:=j;
                                end;
                        end;
                end;
                readln;
        end;
        f[tail].x:=1;
        f[tail].y:=1;
        while(head<tail) do
        begin
                inc(head);
                for i:=1 to 4  do
                begin
                        xx:=f[head].x+dire[i][1];
                        yy:=f[head].y+dire[i][2];
                        if (xx>=1)and(xx<=n)and(yy>=1)and(yy<=m) then
                        begin
                                add:=true;
                                ch:=map[xx][yy];
                                if ch<>'1' then
                                begin
                                        if (ch>='A') then
                                        begin
                                                        map[xx][yy]:='1';
                                                        if (bro[ch].x1=xx)and(bro[ch].y1=yy) then
                                                        begin
                                                                xx:=bro[ch].x2;
                                                                yy:=bro[ch].y2;
                                                        end
                                                         else
                                                        begin
                                                                xx:=bro[ch].x1;
                                                                yy:=bro[ch].y1;
                                                        end;
                                        end
                                         else
                                          map[xx][yy]:='1';
                                               inc(tail);
                                               f[tail].x:=xx;
                                               f[tail].y:=yy;
                                               f[tail].step:=f[head].step+1;
                                               if (xx=n)and(yy=m) then
                                               begin
                                                        if f[tail].step<min then
                                                          min:=f[tail].step;
                                                        can:=true;
                                               end;
                                end;
                        end;
                end;
        end;
        if can then
         writeln(min)
         else
          writeln('No Solution.');
end.

RQ140 分配时间

2011年8月16日 00:21

分组背包

 

var
	u:array[1..11,0..101] of longint;
        f:array[0..100000] of longint;
        i,j,x,t,n,nam:longint;

function max(a,b:longint):longint;
begin
	if a>b then exit(a)
	else exit(b);
end;

begin
        readln(t,n,nam);
	for i:=1 to n do
	begin
		for j:=1 to t do
		read(u[i][j]);
	end;
	for i:=1 to n do
	for x:=t downto 0 do
	for j:=1 to t do
        if x-j-nam>=0 then
        f[x]:=max(f[x],f[x-j-nam]+u[i][j]);
	write(f[t]);
end.

RQ157 晚餐队列安排

2011年8月16日 00:19

记录下就好了

 

#include <stdio.h>

using namespace std;
#define maxn 100000
int rec[maxn][2];

int main()
{
		int n,t,ans,r1,r2;
		ans=0xffffff;
		r1=r2=0;
		scanf("%d",&n);
		for (int i=0;i<n;i++)
		{
				scanf("%d",&t);
				if (t==1) r1++; else r2++;
				rec[i][0]=r1;
				rec[i][1]=r2;
		}
		for (int i=0;i<n;i++)
				if (rec[i][1]+(r1-rec[i][0])<ans)
								ans=rec[i][1]+(r1-rec[i][0]);
		printf("%d",ans);
}

RQ254 占内存的递归函数

2011年8月16日 00:17

模拟就好了,不过要注意顺序....

 

type
int=longint;

var
   m     : array[0..20,0..20,0..20] of boolean;
   f     : array[0..20,0..20,0..20] of longint;
   a,b,c : longint;

function get(a,b,c:longint):longint;
begin
if m[a,b,c] then exit (f[a,b,c]);
   if (a<=0) or (b<=0) or (c<=0) then
      exit(1);
   if (a>20)or(b>20)or(c>20) then exit(get(20,20,20));
   if (a<b) and (b<c) then
   begin
      f[a,b,c]:=get(a-1,b,c)+get(a-1,b-1,c)+get(a-1,b,c-1)-get(a-1,b-1,c-1);
      m[a,b,c]:=true;
      exit(f[a,b,c]);
   end;
   f[a,b,c]:=get(a-1,b,c)+get(a-1,b-1,c)+get(a-1,b,c-1)-get(a-1,b-1,c-1);
   m[a,b,c]:=true;
   exit(f[a,b,c]);
end;

begin
   readln(a,b,c);
   writeln('w(',a,', ',b,', ',c,') = ', get(a,b,c));
   readln(a,b,c);
   while not((a=-1)and(b=-1)and(c=-1)) do
   begin
      writeln('w(',a,', ',b,', ',c,') = ',get(a,b,c));
      readln(a,b,c);
   end;
end.

RQ98 逃亡的准备

2011年8月16日 00:14

此题数据很弱,裸的就可以过了.....

 

var
i,j,k,n,m,tn,tw,tv:longint;
f:array[0..1000000] of longint;

begin
   readln(n,m);
   for i:=1 to n do
   begin
      readln(tn,tw,tv);
      for j:=1 to tn do
	 for k:=m downto tw*j do
	    if f[k]<f[k-tw]+tv then
	       f[k]:=f[k-tw]+tv;
   end;
   writeln(f[m]);
end.

RQ145 打水漂

2011年8月16日 00:11

发下这几天写的吧....

这题是最大子段和

 

{$MODE DELPHI}
const
        maxn=10000;

type
        int=longint;

var
        i,n,ans,num,l:int;
        f     : array[0..maxn+1] of int;
        a,fat : array[1..maxn]   of int;

begin
        readln(n);
        for i:=1 to n do
         read(a[i]);
        ans:=0;
        for i:=1 to n do
        begin
               if f[i-1]>=0 then
               begin
                     f[i]:=f[i-1]+a[i];
                     fat[i]:=i-1;
               end
                else
                 begin
                        f[i]:=a[i];
                        fat[i]:=i;
                 end;
                if f[i]>ans then
                begin
                        ans:=f[i];
                        num:=i;
                end;
        end;
        l:=num;
        while fat[l]<>l do dec(l);
        writeln(l,' ',num);
        writeln(ans);
end.

RQ57

2011年7月25日 20:42

普通二维背包做法就不说了。看到题解里有一个优化,觉得比较巧妙,说不太清楚,大致是先把time[i]=maxtime-time[i],f[i][j]表示rp是i,rmb是j下的最大剩余时间,然后一般的方程直接套上就行了,这样弄一下把所有东西都满足了...

#include <iostream>

using namespace std;

#define mtime 20000
#define size 100

int main()
{
    int n,maxrmb,maxrp;
    int time[size];
    int rp[size];
    int rmb[size];
    int f[300][300];
    cin >> n;
    for (int i=0;i<n;i++)
    {
        cin >> rmb[i] >> rp[i] >> time[i];
        time[i]=mtime-time[i];
    }
    cin >> maxrmb >> maxrp;
    for (int i=0;i<n;i++)
        for (int j=maxrp;j>=rp[i];j--)
            for (int k=maxrmb;k>=rmb[i];k--)
                if (f[j-rp[i]][k-rmb[i]]+time[i]>f[j][k])
                    f[j][k]=f[j-rp[i]][k-rmb[i]]+time[i];
    cout << mtime-f[maxrp][maxrmb] % mtime;
}

这个..又混了10天...不行啊...