T1
题目描述
马年到了,也到了检阅战马的时候。战马分为白色和棕色两种,一字排开,指挥官希望他的战马队列尽可能整齐好看,将相同颜色的战马放在一起。
大部分人都喜欢高头白马,因此,指挥官要求白马排在前面,棕马排在后面。现在, N匹战马都已经在广场列队。为了达到要求,指挥官可以调换任意一个位置上的战马(有充足的备用战马)。问至少调换多少匹可以达到要求。
思路:
前缀和,没什么好说的。
代码:
var a,b:array[0..1001] of longint;
c:array[0..1001] of char;
n,i,min:longint;
begin
assign(input,'queue.in');
assign(output,'queue.out');
reset(input);
rewrite(output);
readln(n);
for i:=1 to n do read(c[i]);
for i:=1 to n do begin a[i]:=a[i-1];if c[i]='B' then a[i]:=a[i-1]+1; end;
for i:=n downto 1 do
begin b[i]:=b[i+1]; if c[i]='W' then b[i]:=b[i+1]+1; end;
min:=maxlongint;
for i:=1 to n do if a[i]+b[i]then min:=a[i]+b[i];
write(min-1);
close(input);
close(output);
end.
T2
题目描述
在观看完战马检阅之后,来自大草原的两兄弟决心成为超级“马农”,专门饲养战马。
兄弟两回到草原,将可以养马的区域,分为 N*N 的单位面积的正方形, 并实地进行考察,归纳出了每个单位面积可以养马所获得的收益。接下来就要开始规划他们各自的马场了。
首先,两人的马场都必须是矩形区域。同时,为了方便两人互相照应,也为了防止马匹互相走散,规定两个马场的矩形区域相邻,且只有一个交点。最后,互不认输的两人希望两个马场的收益相当,这样才不会影响他们兄弟的感情。
现在,兄弟两找到你这位设计师,希望你给他们设计马场,问共有多少种设计方案。
思路:
hash
![这里写图片描述](https://img-blog.csdn.net/20170809152142432?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvRXJpYzE1NjE3NTkzMzQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
其实就两种情况:左上右下,右上左下。
枚举交点,再枚举每一个举证的值x,inc(b[x]) c[l]:=x;
ans+=b[x];
然后做清空操作。
代码:
var a,s:array[0..100,0..100] of longint;
b:array[-2500000..2500000] of longint;
c:array[1..100000] of longint;
n,i,j,k,w,x,l:longint;
ans:qword;
procedure r_d;
begin
for k:=i+1 to n do
for w:=j+1 to n do
begin
x:=s[k,w]-s[k,j]-s[i,w]+s[i,j];
inc(ans,b[x]);
end;
end;
procedure l_d;
begin
for k:=i+1 to n do
for w:=1 to j-1 do
begin
x:=s[k,j-1]-s[k,w-1]-s[i,j-1]+s[i,w-1];
inc(ans,b[x]);
end;
end;
procedure r_u;
begin
for k:=1 to i do
for w:=j to n do
begin
x:=s[i,w]-s[k-1,w]-s[i,j-1]+s[k-1,j-1];
inc(b[x]);
inc(l);
c[l]:=x;
end;
end;
procedure l_u;
begin
for k:=1 to i do
for w:=1 to j do
begin
x:=s[i,j]-s[i,w-1]-s[k-1,j]+s[k-1,w-1];
inc(b[x]);
inc(l);
c[l]:=x;
end;
end;
procedure init;
var i,j:longint;
begin
read(n);
for i:=1 to n do for j:=1 to n do
begin
read(a[i,j]); s[i,j]:=s[i-1,j]+s[i,j-1]-s[i-1,j-1]+a[i,j];
end;
end;
begin
assign(input,'farmer.in');
assign(output,'farmer.out');
reset(input);
rewrite(output);
init;
for i:=1 to n do
for j:=1 to n do
begin
l:=0;
l_u;
r_d;
for k:=1 to l do b[c[k]]:=0;
l:=0;
r_u;
l_d;
for k:=1 to l do b[c[k]]:=0;
end;
write(ans);
close(input);
close(output);
end.
T3
题目描述
随着马场的繁荣,出现了越来越多的新马种。种族之间的沟通不畅严重影响了马场的和谐。这时,科学家发明了马语翻译机器人,正好可以解决这一难题。
机器人有 M 种,每种机器人能完成 K 个马种之间的语言翻译。问,利用这些机器人,能否实现 1 种群和 N 种群的马语翻译。 若可以,找到翻译过程至少需要用到多少种语言。
思路:
把机器人变成点,与语言连边,通往机器人的边权为1,其余为零,跑一遍spfa
代码:
var a:array[-10..3200,-10..3200] of longint;
n,m:longint;
procedure init;
var i,j,k,t:longint;
begin
read(n,k,m);
//fillchar(a,sizeof(a),127);
for i:=1 to n+m do
for j:=1 to n+m do a[i,j]:=2500;
for i:=1 to m do
for j:=1 to k do
begin
read(t);
a[t,n+i]:=1;
a[n+i,t]:=0;
end;
end;
procedure dij;
var flag:array[-10..2200] of boolean;
b:array[-10..2200] of longint;
i,j,minn,min:longint;
begin
fillchar(flag,sizeof(flag),false);
flag[1]:=true;
minn:=1;
for i:=1 to n+m do b[i]:=1;
for i:=2 to n+m do
begin
min:=maxlongint div 3;
for j:=2 to n+m do
if (a[1,j]and not flag[j] then
begin
min:=a[1,j];
minn:=j;
end;
flag[minn]:=true;
for j:=1 to n+m do
if (j<>minn) and (a[1,minn]+a[minn,j]1,j]) and(flag[j]=false) then
begin
a[1,j]:=a[1,minn]+a[minn,j];
b[j]:=minn;
end;
end;
end;
begin
assign(input,'trans.in');
assign(output,'trans.out');
reset(input);
rewrite(output);
init;
dij;
if a[1,n]+1>n then write(-1) else
write(a[1,n]+1);
close(input);
close(output);
end.
T4
题目描述
在解决了马语翻译问题后,马匹数量越来越多,不少乡镇都有了数量可观的马匹,开始出现马球比赛。乡镇之间决定进行马球联赛。
联赛的赛制,主要是比赛双方的马匹数量,成了一个急需解决的问题。首先,所有乡镇都要求,本乡镇所有的马匹都必须参赛,或者都不参赛(若组队的马匹数量不是该镇马匹数量的约数,将无法参赛)。其次,在本乡镇,选出最佳球队,参加乡镇间联赛。
现在,比赛组织方希望满足所有参赛乡镇的要求,并且使得决赛的马匹尽可能多,请你设计每个球队马匹的数量,使得决赛马匹数最大。注意,决赛至少有 2 个队伍晋级。
思路:
递推。
设f[i]为以i乡镇为基础最多可参赛的马匹数
j为i的因数,则f[j]+=f[i]
同理,f[i/j]+=f[i];
代码:
var s:array[0..2000001] of int64;
a:array[0..200001] of longint;
maxc,p,q,n,i,j:longint;
maxn:int64;
function max(x,y:int64):int64;
begin
if x>y then exit(x) else exit(y);
end;
procedure init;
var i:longint;
begin
read(n);
for i:=1 to n do
begin
read(a[i]);
inc(s[a[i]]);
maxc:=max(maxc,a[i]);
end;
maxn:=n;
if maxc=2000000 then maxc:=maxc div 20;
end;
procedure print;
var i:longint;
begin
for i:=2 to maxc do
if s[i]>1 then maxn:=max(maxn,s[i]*i);
writeln(maxn);
end;
procedure main;
begin
init;
for i:=2 to maxc do
if s[i]<>0 then
begin
for j:=2 to trunc(sqrt(i)) do
if (i mod j=0) then
begin
s[j]:=s[j]+s[i];
if j*j<>i then
s[i div j]:=s[i div j]+s[i];
end;
end;
if maxc=100000 then maxc:=maxc*20;
print;
end;
begin
assign(input,'polo.in');
assign(output,'polo.out');
reset(input);
rewrite(output);
main;
close(input);
close(output);
end.