您的位置:首页 > 其它

2017.8.09 SSL 模拟赛

2017-08-09 16:42 85 查看
T1:

17倍 Times17:

题目大意:

给出一个二进制数N,求出17*N的二进制数的值。

数据范围:

N的位数不超过1000位。

题解:

枚举:

不难发现,对于二进制上的第i位,代表的是2^i次方,而他的十七倍则是他的第i+4位+1且他本身这一位为1,然后直接枚举这个数的位数,如果这一位存在1,则给他的i+4的位+1,因为他本身已经有一个了,所以1倍+16倍就可以了。

时间复杂度:O(N的长度)

var
st:ansistring;
i,long,m:longint;
a,b:array [-1..1005] of longint;
begin
readln(st);
long:=length(st);
for i:=1005-long+1 to 1005 do a[i]:=ord(st[long-(1005-i)])-48;
for i:=1005 downto 1005-long+1 do if a[i]=1 then b[i-4]:=b[i-4]+1;
for i:=1005 downto 1005-long-6 do a[i]:=a[i]+b[i];
for i:=1005 downto 1006-long-6 do
if a[i] div 2>=1 then
begin
a[i-1]:=a[i-1]+a[i] div 2;
a[i]:=a[i] mod 2;
end;
m:=1;
while (a[m]=0) and (m<=1005) do inc(m);
for i:=m to 1005 do write(a[i]);
end.


T2:

马蹄印 Horseshoes:

题目大意:

对于一个完美的平衡序列,是先一定数量的左括号然后是与左括号相同数量的右括号。例如:(((())))。

农场是一个N*N的方格,每个小方格中都有一个马蹄印。从方格的最左上角的地方开始出发,然后每次可以向上或者向下或者向左或者向右移动一步,不能重复经过任何小方格,使得他走过的每个小方格中的马蹄印能够组成一个完美的平衡序列,求这个序列的长度。

数据范围:2<=N<=5

题解:

dfs:

这题的数据好尴尬,裸裸的搜索就可以了,

然后注意一下几个要求:

①每个点只能走一遍

②能向上下左右走

然后要优美的同学,还有一个优化,就是如果当前搜的序列已经出现了’)’则它之后搜到了’(‘就直接exit。

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

var
a:array [0..6,0..6] of char;
b:array [0..6,0..6] of boolean;
i,j,n,max:longint;

function check(aa,bb:longint):boolean;
begin
if (b[aa,bb]) or (aa<1) or (aa>n) or (bb<1) or (bb>n) then exit(false);
exit(true)
end;

procedure dfs(x,y,left,right:longint;pd:boolean);
var
i,p,q:longint;
pdd:boolean;
begin
b[x,y]:=true;
p:=0; q:=0;
pdd:=false;
if a[x,y]='('
then begin if not(pd) then p:=1 end
else begin pdd:=true; q:=1; end;
if (p=1) or (q=1)
then begin
if left+p=right+q then
if left+p>max then max:=left+p;
for i:=1 to 4 do
if check(x+dx[i],y+dy[i])
then dfs(x+dx[i],y+dy[i],left+p,right+q,pdd);
end;
b[x,y]:=false;
end;

begin
readln(n);
for i:=1 to n do
begin
for j:=1 to n do read(a[i,j]);
readln;
end;
dfs(1,1,0,0,false);
writeln(2*max);
end.


T3:

排队的奶牛 Cows in a Row:

题目大意:

农夫约翰的N只奶牛排成了一条直线,从左到右第i只奶牛的编号是Bi。约翰认为他的奶牛队列中存在某段连续区间都是相同序号的,那他的队列就非常的美观。为了创造这样的一个连续区间,约翰决定将某个特定的序号的奶牛全部剔除队列,然后求这样以后,能出现的最长的区间长度。

数据范围:

1<=N<=1000,奶牛序号的范围是0到1000000。

题解:

因为只有N头牛,而序号只有1000000最大,所以我们开个桶去塞,将出现的序号塞出来。

因为序号不多于1000个,就直接枚举每种奶牛被剔除的情况。

最后在出现过的序号中找答案。

时间复杂度:O(N^2)

var
a:Array [0..1000001] of boolean;
ans:array [0..1000001] of longint;
p,c:Array [0..1001] of longint;
i,j,n,max:longint;

procedure find(x:longint);
var
i,j,k:longint;
begin
i:=1;
while i<=n do
begin
while (c[i]=x) and (i<n) do inc(i);
j:=0;
k:=1;
while ((c[i+j+1]=x) or (c[i]=c[i+j+1])) and (i+j+1<=n) do
begin
inc(j);
if c[i+j]=c[i] then inc(k);
end;
if k>ans[c[i]]
then ans[c[i]]:=k;
i:=i+j+1;
end;
end;

begin
readln(n);
for i:=1 to n do
begin
readln(c[i]);
if not(a[c[i]])
then begin
inc(p[0]);
p[p[0]]:=c[i];
end;
a[c[i]]:=true;
end;
for i:=1 to p[0] do find(p[i]);

for i:=1 to p[0] do
if ans[p[i]]>max then max:=ans[p[i]];
writeln(max);
end.


T4:

景观美化 Landscaping:

题目大意:

花园由N块花圃组成,第i块花圃初始的时候有Ai数量的泥土。为了达到美化的目的,必须使得第i块花圃的泥土数量Ai变成Bi。

约翰有三个选择:

①买一个单位的泥土放进任意花圃中,代价是X;

②将一个单位的泥土从某一个花圃中除去,代价是Y;

③将第i块花圃中的一个单位的泥土搬运到第j块花圃中,大家是Z*|i-j|。

数据范围:

1<=N<=100,

0<=Ai,Bi<=10,

0<=X,Y,Z<=1000。

题解:

这题有2种做法:

①这题我们将每个花圃的泥土都分开来,例如,我们将3,1,4,1的泥土数量分成1,1,1,2,3,3,3,3,4。三个1表示第一个花圃中有3个单位的泥土,以此类推。

然后目标状态跟当前状态都这样做

接着我们设f[i,j]表示用了前i个当前状态转化到前j个目标状态所需要的最小代价。

然后DP:

初值:

i=0 则 j个全部直接购买:f[i,j]=j*x

j=0 则 i个全部直接除去:f[i,j]=i*y

f[i,j]=min(f[i-1,j]+y,f[i,j-1]+x,f[i-1,j-1]+z*abs(a[i]-b[j]))

f[i-1,j]+y

i-1个转化到j个的最小值+直接除去第i个

f[i,j-1]+x

i个转化到j-1个的最小值+直接买掉第j个

f[i-1,j-1]+z*abs(a[i]-b[j])

i-1个转化到j-1个的最小值+用第i个转化到第j个

时间复杂度:O(a[i]总和 * b[i]总和)

var
f:array [0..1001,0..1001] of longint;
a,b:array [0..1001] of longint;
i,j,n,x,y,z,a1,b1:longint;

function min(aa,bb:longint):longint;
begin
if aa>bb then exit(bb);
exit(aa);
end;

begin
readln(n,x,y,z);
for i:=1 to n do
begin
readln(a1,b1);
for j:=1 to a1 do
begin
inc(a[0]);
a[a[0]]:=i;
end;
for j:=1 to b1 do
begin
inc(b[0]);
b[b[0]]:=i;
end;
end;
for i:=0 to a[0] do
for j:=0 to b[0] do
begin
if i=0 then f[i,j]:=j*x
else if j=0 then f[i,j]:=i*y
else f[i,j]:=min(f[i-1,j-1]+z*abs(a[i]-b[j]),min(f[i,j-1]+x,f[i-1,j]+y));
end;
writeln(f[a[0],b[0]]);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: