POJ2329 Nearest number - 2——Dp恶心题

按照从左上开始、从右上开始、从左下开始、从右下开始四个顺序来Dp,记录路径,如果最小路径不唯一那么这个点的权值为0.

极其考察细心和耐心,数据还是比较弱的……

代码:

program poj2329;

const

	maxn=205;

var

	i,j,m,p,q,n					:longint;

	map,f,dp					:array[0..maxn,0..maxn]of longint;

	rec,g						:array[0..maxn,0..maxn]of record x,y:longint;end;

	

function min(i,j:longint):longint;

begin

	if i<j then exit(i);exit(j);

end;

	

begin

	readln(n);

	for i:=1 to n do for j:=1 to n do read(map[i,j]);

	fillchar(dp,sizeof(dp),127);

	for i:=1 to n do

		for j:=1 to n do

			if map[i,j]<>0 then

				begin

					dp[i,j]:=0;

					rec[i,j].x:=i;

					rec[i,j].y:=j;

				end else

				begin

					dp[i,j]:=min(dp[i,j-1],dp[i-1,j])+1;

					if dp[i,j]<maxint then

						begin

							if dp[i,j-1]=dp[i-1,j] then

								begin

									if (rec[i,j-1].x=rec[i-1,j].x)and(rec[i,j-1].y=rec[i-1,j].y) then

										rec[i,j]:=rec[i,j-1] else

											begin

												rec[i,j].x:=i;

												rec[i,j].y:=j;

											end;

								end else if dp[i,j-1]<dp[i-1,j] then

									begin

										if (map[i,j-1]=0)and(rec[i,j-1].x=i)and(rec[i,j-1].y=j-1) then

											begin

												rec[i,j].x:=i;rec[i,j].y:=j;

											end else rec[i,j]:=rec[i,j-1];

									end else

										begin

											if (map[i-1,j]=0)and(rec[i-1,j].x=i-1)and(rec[i-1,j].y=j) then

												begin

													rec[i,j].x:=i;rec[i,j].y:=j;

												end else rec[i,j]:=rec[i-1,j];

										end;

						end;

				end;

	fillchar(f,sizeof(f),127);

	for i:=1 to n do

		for j:=1 to n do

			begin

				g[i,j].x:=0;g[i,j].y:=0;

			end;

	for i:=1 to n do

		for j:=n downto 1 do

			if map[i,j]<>0 then

				begin

					f[i,j]:=0;

					g[i,j].x:=i;

					g[i,j].y:=j;

				end else

				begin

					f[i,j]:=min(f[i,j+1],f[i-1,j])+1;

					if f[i,j]<maxint then

						begin

							if f[i,j+1]=f[i-1,j] then

								begin

									if (g[i,j+1].x=g[i-1,j].x)and(g[i,j+1].y=g[i-1,j].y) then

										g[i,j]:=g[i,j+1] else

											begin

												g[i,j].x:=i;

												g[i,j].y:=j;

											end;

								end else if f[i,j+1]<f[i-1,j] then

									begin

										if (map[i,j+1]=0)and(g[i,j+1].x=i)and(g[i,j+1].y=j+1) then

											begin

												g[i,j].x:=i;g[i,j].y:=j;

											end else g[i,j]:=g[i,j+1];

									end else

										begin

											if (map[i-1,j]=0)and(g[i-1,j].x=i-1)and(g[i-1,j].y=j) then

												begin

													g[i,j].x:=i;g[i,j].y:=j;

												end else g[i,j]:=g[i-1,j];

										end;

						end;

					if f[i,j]<dp[i,j] then

						begin

							dp[i,j]:=f[i,j];

							rec[i,j]:=g[i,j];

						end else if f[i,j]=dp[i,j] then

							begin

								if (rec[i,j].x=0)and(rec[i,j].y=0)then rec[i,j]:=g[i,j];

								if ((g[i,j].x<>rec[i,j].x)or(g[i,j].y<>rec[i,j].y))and((g[i,j].x<>0)or(g[i,j].y<>0)) then

									begin

										rec[i,j].x:=i;rec[i,j].y:=j;

									end;

							end;

				end;

	fillchar(f,sizeof(f),127);

	for i:=1 to n do

		for j:=1 to n do

			begin

				g[i,j].x:=0;g[i,j].y:=0;

			end;

	for i:=n downto 1 do

		for j:=n downto 1 do

			if map[i,j]<>0 then

				begin

					f[i,j]:=0;

					g[i,j].x:=i;

					g[i,j].y:=j;

				end else

				begin

					f[i,j]:=min(f[i,j+1],f[i+1,j])+1;

					if f[i,j]<maxint then

						begin

							if f[i,j+1]=f[i+1,j] then

								begin

									if (g[i,j+1].x=g[i+1,j].x)and(g[i,j+1].y=g[i+1,j].y) then

										g[i,j]:=g[i,j+1] else

											begin

												g[i,j].x:=i;

												g[i,j].y:=j;

											end;

								end else if f[i,j+1]<f[i+1,j] then

									begin

										if (map[i,j+1]=0)and(g[i,j+1].x=i)and(g[i,j+1].y=j+1) then

											begin

												g[i,j].x:=i;g[i,j].y:=j;

											end else g[i,j]:=g[i,j+1];

									end else

										begin

											if (map[i+1,j]=0)and(g[i+1,j].x=i+1)and(g[i+1,j].y=j) then

												begin

													g[i,j].x:=i;g[i,j].y:=j;

												end else g[i,j]:=g[i+1,j];

										end;

						end;

					if f[i,j]<dp[i,j] then

						begin

							dp[i,j]:=f[i,j];

							rec[i,j]:=g[i,j];

						end else if f[i,j]=dp[i,j] then

							begin

								if (rec[i,j].x=0)and(rec[i,j].y=0)then rec[i,j]:=g[i,j];

								if ((g[i,j].x<>rec[i,j].x)or(g[i,j].y<>rec[i,j].y))and((g[i,j].x<>0)or(g[i,j].y<>0)) then

									begin

										rec[i,j].x:=i;rec[i,j].y:=j;

									end;

							end;

				end;

	for i:=1 to n do

		for j:=1 to n do

			begin

				g[i,j].x:=0;g[i,j].y:=0;

			end;

	fillchar(f,sizeof(f),127);

	for i:=n downto 1 do

		for j:=1 to n do

			if map[i,j]<>0 then

				begin

					f[i,j]:=0;

					g[i,j].x:=i;

					g[i,j].y:=j;

				end else

				begin

					f[i,j]:=min(f[i,j-1],f[i+1,j])+1;

					if f[i,j]<maxint then

						begin

							if f[i,j-1]=f[i+1,j] then

								begin

									if (g[i,j-1].x=g[i+1,j].x)and(g[i,j-1].y=g[i+1,j].y) then

										g[i,j]:=g[i,j-1] else

											begin

												g[i,j].x:=i;

												g[i,j].y:=j;

											end;

								end else if f[i,j-1]<f[i+1,j] then

									begin

										if (map[i,j-1]=0)and(g[i,j-1].x=i)and(g[i,j-1].y=j-1) then

											begin

												g[i,j].x:=i;g[i,j].y:=j;

											end else g[i,j]:=g[i,j-1];

									end else

										begin

											if (map[i+1,j]=0)and(g[i+1,j].x=i+1)and(g[i+1,j].y=j) then

												begin

													g[i,j].x:=i;g[i,j].y:=j;

												end else g[i,j]:=g[i+1,j];

										end;

						end;

					if f[i,j]<dp[i,j] then

						begin

							dp[i,j]:=f[i,j];

							rec[i,j]:=g[i,j];

						end else if f[i,j]=dp[i,j] then

							begin

								if (rec[i,j].x=0)and(rec[i,j].y=0)then rec[i,j]:=g[i,j];

								if ((g[i,j].x<>rec[i,j].x)or(g[i,j].y<>rec[i,j].y))and((g[i,j].x<>0)or(g[i,j].y<>0)) then

									begin

										rec[i,j].x:=i;rec[i,j].y:=j;

									end;

							end;

				end;

	for i:=1 to n do

		begin

			for j:=1 to n-1 do

				write(map[rec[i,j].x,rec[i,j].y],' ');

			writeln(map[rec[i,n].x,rec[i,n].y]);

		end;

end.

你可能感兴趣的:(number)