T1:
这题我们可以发现:
长方形的面积就是
a* i + b * j -a*b
现在i,j是未知的
我们进一步思考:
发现我们连接圆心到矩形A的一点,就可以有勾股求出圆心到矩形A的a边的距离
即 (i/2)^2=r^2- (a/2)^2
而后可以求出i
j同理可求
然后我们去枚举a,b即可
时间复杂度:((2r)^2)
var
r,a,b,i,j:longint;
ans,sum:extended;
begin
readln(r);
for i:=1 to 2*r do
for j:=1 to 2*r do
begin
sum:=i*sqrt(sqr(r)-sqr(i/2))*2+j*sqrt(sqr(r)-sqr(j/2))*2-i*j;
if sum>ans then
begin
ans:=sum;
a:=i;
b:=j;
end;
end;
writeln(a);
writeln(b);
end.
T2:
这题其实没什么好讲的,选择排序然后注意判断就可以了。。。。
时间复杂度:O(N^2)
N那么小不用快排那么麻烦啦
var
a:array [0..101,1..2] of string;
b,ans:array [0..101] of longint;
n,i,j:longint;
s:string;
begin
readln(n);
for i:=1 to n do
begin
readln(s);
j:=pos('.',s);
if j<>0 then
begin
a[i,2]:=copy(s,j+1,length(s)-j);
delete(s,j,length(s)-j+1);
end;
a[i,1]:=s;
b[i]:=i;
end;
for i:=1 to n-1 do
for j:=i+1 to n do
if ((a[i,2]='') and (a[j,2]<>'')) or
((a[i,2]=a[j,2]) and (a[i,1]>a[j,1])) or
((a[i,2]<>'') and (a[j,2]<>'') and (a[i,2]>a[j,2]))
then begin
a[0]:=a[i];a[i]:=a[j];a[j]:=a[0];
b[0]:=b[i];b[i]:=b[j];b[j]:=b[0];
end;
for i:=1 to n do
ans[b[i]]:=i;
for i:=1 to n do writeln(ans[i]);
end.
T3:
这题其实搜索,然后记忆化:
我们用f[i,j,k]去表示以a[i,j]为起点向4个方向能走的最长等差数列的长度。
然后去搜即可。
你可以在做f[i,j,k]顺便把经过的[ii,jj]的f[ii,jj,kk]做了,然后打个标记,所以跑得特别的快。
时间复杂度:O(4NM)
const
dx:array[1..4] of integer=(0,0,1,-1);
dy:array[1..4] of integer=(-1,1,0,0);
var
f:array [0..101,0..101,1..4] of longint;
a:array [0..101,0..101] of longint;
i,j,k,ans,n,m:longint;
function check(aa,bb:longint):boolean;
begin
if (aa<1) or (aa>n) or (bb<1) or (bb>m) then exit(false);
exit(true);
end;
function dfs(x,y,z:longint):longint;
var
i,p,q:longint;
begin
dfs:=1;
for i:=1 to 4 do
begin
p:=x+dx[i];
q:=y+dy[i];
if check(p,q) then
if a[p,q]-a[x,y]=z then
begin
if f[x,y,i]=0 then f[x,y,i]:=dfs(p,q,z)+1;
if f[x,y,i]>dfs then dfs:=f[x,y,i];
end;
end;
end;
begin
readln(n,m);
for i:=1 to n do
begin
for j:=1 to m do read(a[i,j]);
readln;
end;
for i:=1 to n do
for j:=1 to m do
for k:=1 to 4 do
begin
if check(i+dx[k],j+dy[k]) then
if a[i+dx[k],j+dy[k]]-a[i,j]>0 then
f[i,j,k]:=dfs(i+dx[k],j+dy[k],a[i+dx[k],j+dy[k]]-a[i,j]);
inc(f[i,j,k]);
end;
for i:=1 to n do
for j:=1 to m do
for k:=1 to 4 do
if f[i,j,k]>ans then ans:=f[i,j,k];
writeln(ans);
end.
T4:
这题其实就是取n-1条边,使它变成一棵连通图,然后最大的边最小!如果有克鲁斯卡尔去做,很明显N^3,会炸,所以我们要优化!
我们先将边排序,然后从小到大加边,这样能保证树最大的边最小!
每次加边的时候,要判断2个点并不能互相到达,这点可以用并查集实现!
加到n-1条边的时候,这条边就是答案!
时间复杂度:O(N^2log N)
var
c:array [0..1000001,1..2] of longint;
a:array [0..1001,0..1001] of real;
f,x,y,r:array [0..1001] of longint;
d:array [0..1000001] of real;
i,j,k,l,n,m:longint;
min,ans:real;
function find(x:longint):longint;
begin
if f[x]=x then exit(x);
f[x]:=find(f[x]);
exit(f[x]);
end;
procedure qsort(l,r:longint);
var
mid,i,j:longint;
begin
if l>=r then exit;
i:=l; j:=r;
mid:=(l+r) div 2;
repeat
while d[i]do inc(i);
while d[j]>d[mid] do dec(j);
if i<=j then
begin
d[0]:=d[i];d[i]:=d[j];d[j]:=d[0];
c[0]:=c[i];c[i]:=c[j];c[j]:=c[0];
inc(i); dec(j);
end;
until i>j;
qsort(i,r);
qsort(l,j);
end;
begin
readln(n);
for i:=1 to n do
begin
readln(x[i],y[i],r[i]);
f[i]:=i;
end;
m:=0;
for i:=1 to n-1 do
for j:=i+1 to n do
begin
a[i,j]:=sqrt(sqr(x[i]-x[j])+sqr(y[i]-y[j]))-r[i]-r[j];
if a[i,j]<0 then a[i,j]:=0;
inc(m);
d[m]:=a[i,j];
c[m,1]:=i;
c[m,2]:=j;
end;
qsort(1,m);
k:=1;
ans:=d[1];
f[c[1,2]]:=c[1,1];
for i:=2 to m do
begin
if k=n-1 then break;
if find(c[i,1])<>find(c[i,2])
then begin
inc(k);
f[find(c[i,2])]:=find(c[i,1]);
end;
end;
if d[i-1]>trunc(d[i-1]) then d[i-1]:=d[i-1]+0.5;
writeln(d[i-1]:0:0);
end.