Đề bài: http://vn.spoj.com/problems/NKGOLF/
Thuật toán:
- (đang cập nhập)
Code:
#include
#include
#include
#include
#include
#include
#include
#include
#include
Just another WordPress site
Đề bài: http://vn.spoj.com/problems/NKGOLF/
Thuật toán:
Code:
#include
#include
#include
#include
#include
#include
#include
#include
#include
Đề bài: http://vn.spoj.com/problems/CTNOWN/
Thuật toán:
Code:
uses math;
const fi='';
fo='';
maxn=350;
var n,i,j :longint;
dem :longint;
nto :array[1..maxn] of longint;
cx :array[1..maxn] of boolean;
f :array[0..maxn,0..maxn] of qword;
t,tt,k :longint;
res,tam :qword;
procedure sangnto;
var i,j :longint;
begin
for i:=2 to trunc(sqrt(maxn)) do
if cx[i]=false then
begin
j := i*i;
while (j<=maxn) do
begin
cx[j]:=true;
j := j+i;
end;
end;
for i:=2 to maxn do
if cx[i]=false then
begin
inc(dem);
nto[dem] := i;
end;
end;
function max(x,y : qword) : qword;
var tg : qword;
begin
if x>y then exit(x) else exit(y);
end;
procedure main;
begin
assign(input,fi);reset(input);
assign(output,fo);rewrite(output);
sangnto;
read(t);
for i:=0 to dem do
for j:=0 to maxn do f[i,j] := 1;
for i:=1 to dem do
begin
for j:=1 to maxn do
begin
f[i,j] := f[i-1,j];
tam:=1;
while tam*nto[i]<=j do
begin
tam := tam * nto[i];
f[i,j] := max(f[i,j], f[i-1,j-tam]*tam );
end;
end;
end;
for tt := 1 to t do
begin
read(n);
writeln(f[dem,n]);
end;
close(input);close(output);
end;
procedure __;
begin
end;
begin
__ ;
main;
__ ;
end.
Đề bài: http://vn.spoj.com/problems/DHFRBUS/
Thuật toán:
Code:
{$inline on}
const fi ='';
fo ='';
maxN =trunc(1e5)*2;
maxM =trunc(1e5)*10;
maxK =5;
oo =2*trunc(1e12);
type Tadj =record
v,w,link:int64;
end;
THeap =record
v1,v2:int64;
end;
Arr1 =array[0..maxN] of int64;
Arr2 =array[0..maxM] of Tadj;
Arr4 =array[0..maxN*maxK] of THeap;
Arr5 =array[0..maxN,0..maxK] of int64;
var n, m, k :longint;
Adj :arr2;
Head :arr1;
s, t :longint;
d :arr5;
Pos :arr5;
H :arr4;
nHeap :longint;
c :longint;
//heapmin;
procedure hv(var a, b:int64);
var tg :int64;
begin
tg:=a;a:=b;b:=tg;
end;
procedure UpHeap(i:longint);
begin
if (i<=1) or (d[H[i div 2].v1,H[i div 2].v2]<=d[H[i].v1,H[i].v2]) then exit;
hv(Pos[H[i div 2].v1,H[i div 2].v2],Pos[H[i].v1,H[i].v2]);
hv(H[i div 2].v1,H[i].v1);
hv(H[i div 2].v2,H[i].v2);
UpHeap(i div 2);
end;
procedure DownHeap(i:longint);
var j :longint;
begin
j:=i*2;
if j>nHeap then exit;
if (j0 do
begin
v:=adj[i].v;
w:=adj[i].w;
if d[v,x]>d[u,x]+w then
begin
d[v,x]:=d[u,x]+w;
Update(v,x);
end;
if (xd[u,x]) then
begin
d[v,x+1]:=d[u,x];
Update(v,x+1);
end;
i:=adj[i].link;
end;
until nHeap=0;
ans:=oo;
ans:=d[t,k];
{for x:=0 to k do
if d[t,x]
Đề bài: http://vn.spoj.com/problems/DHLOCK/
Thuật toán:
Code:
const fi='';
fo='';
maxn=300;
var i,j,n,k:longint;
kiluc,kq,tam:longint;
a,b,c:array[1..maxn] of longint;
procedure xuly;
var kk:longint;
tmp:longint;
begin
for kk:=0 to n-1 do
begin
for i:=1 to n do
begin
if i+kk>n then tam:=(i+kk) mod n else tam:=i+kk;
if b[tam]>=a[i] then c[i]:=b[tam]-a[i]
else c[i]:=b[tam]+k-a[i]+1;
end;
for i:=1 to n do
begin
kq:=0;
tam:=c[i];
for j:=1 to n do
if c[j]>=tam then inc(kq,c[j]-tam)
else inc(kq,c[j]+k-tam+1);
if kq+kk+tam=a[i] then inc(kiluc,b[i]-a[i])
else inc(kiluc,b[i]+k-a[i]+1);
end;
begin
assign(input,fi);reset(input);
assign(output,fo);rewrite(output);
readln(n,k);
for i:=1 to n do read(a[i]);
for j:=1 to n do read(b[j]);
init;
xuly;
writeln(kiluc);
close(input);close(output);
end.
Đề bài: http://vn.spoj.com/problems/NKPALIN/
Thuật toán:
Gọi F[i][j] là độ dài xâu đối xứng dài nhất trong đoạn S[i..j]. Khi đó:
Bạn có thể đọc code bên dưới để hiểu hơn.
Code:
Program Xaucon;
Var s,st,st1:ansistring;
i,j:integer;
F: Array[1..2000,1..2000] Of Integer;
Procedure nhap;
Begin
Readln(s);
For i:=1 to length(s) do F[i,i]:=1;
Writeln;Writeln;
end;
Function max(a,b:integer):integer;
Begin
If a>b then exit(a) else exit(b);
End;
Procedure Solve;
Begin
For i:=length(s) downto 1 do
For j:=i+1 to length(s) do
If s[i]=s[j] then
F[i,j]:=F[i+1,j-1]+2
else F[i,j]:= max(F[i+1,j],F[i,j-1]);
End;
Procedure PrintResult;
Begin
i:=1;
j:=length(s);
While (i<=j) do
Begin
If s[i]=s[j] then
Begin
st:=st+s[i];
st1:=s[j]+st1;
inc(i);
dec(j);
end
Else
If F[i+1,j]=F[i,j] then inc(i) else dec(j);
End;
If F[1,length(s)] mod 2 =1 then delete(st1,1,1);
st:=st+st1;
Writeln(st);
end;
Begin
nhap;
Solve;
PrintResult;
readln
end.
đề bài: http://vn.spoj.com/problems/CREC01/
Thuật toán:
Code:
Pascal:
const fi ='';
fo ='';
oo =1000;
var a :array[0..oo,0..oo] of 0..1;
l,h,dem:array[0..oo+1] of int64;
m, n :longint;
procedure Optimize;
var i, j :longint;
ans :int64;
begin
fillchar(h, sizeof(h),0);
ans:=0;
for i:=1 to m do
begin
for j:=1 to n do
begin
if a[i,j]=1 then begin
l[j]:=j;
h[j]:=h[j]+1;
while h[l[j]-1]>h[j] do
l[j]:=l[l[j]-1];
dem[j]:=h[j]*(j-l[j]+1)+dem[l[j]-1];
ans:=ans+dem[j];
//writeln(ans,'==');
//if (i=3) and (j=2) then writeln(dem[1]);
end
else begin
dem[j]:=0;
l[j]:=0;
h[j]:=0;
end;
end;
end;
writeln(ans);
end;
procedure run;
var i, j, tg :longint;
s :ansistring;
begin
assign(input,fi);assign(output,fo);
reset(input);rewrite(output);
readln(m, n);
for i:=1 to m do
begin
readln(s);
for j:=1 to n do
val(s[j],a[i,j]);
end;
Optimize;
close(input);close(output);
end;
begin
run;
end.
C++:
using namespace std;
#include
#define BG begin()
#define ED end()
#define st first
#define nd second
#define PB push_back
#define PF push_front
#define FOR(i,a,b) for (long long i=a;i=b; i--)
#define ri(n)({\
int neg=0;\
n=0;\
char ch;\
for(ch=getchar(); ch<'0' || ch>'9'; ch=getchar()) if (ch=='-') neg=1-neg;\
n=ch-48;\
for(ch=getchar(); ch>='0' && ch<='9'; ch=getchar()) n=(n<<3)+(n<<1)+ch-48;\
if (neg) n=-n;\
})
typedef long long ll;
typedef unsigned long long ull;
typedef pair II;
typedef pair LL;
const ll INF=1000000000+7;
const double esp=1e-13;
const double pi=3.141592653589;
ll m, n, a[1001][1001], H[1001], dem[1001], L[1001];
int main()
{
//freopen("CREC01.inp", "r", stdin);
//freopen("CREC01.out", "w", stdout);
cin>>m>>n;
char ch;
FORE(i, 1, m)
FORE(j, 1, n) {
cin>>ch;
a[i][j] = ch - '0';
}
memset(H, 0, sizeof(H));
memset(L, 0, sizeof(L));
memset(dem, 0, sizeof(dem));
long long ans = 0;
FORE(i, 1, m)
FORE(j, 1, n) {
//cout< 1) && (a[i][k-1] == 1) && (H[ k - 1 ] >= H[j]) ) k = L[k - 1];
L[j] = k;
dem[j] = H[j]*(j - L[j] + 1) + dem[L[j] - 1];
ans += dem[j];
//cout<
Đề bài: http://vn.spoj.com/problems/NKSTEP/
Thuật toán:
Code:
const fi='';
fo='';
maxn=100000;
var t:longint;
a,l,c:array[1..maxn] of int64;
x,y,hold,tmp,max,k,w:int64;
i,j:longint;
res:int64;
f:text;
procedure nhap;
begin
assign(f,fi);
reset(f);
readln(f,t);
max:=-1;
for i:=1 to t do
begin
readln(f,x,y);
a[i]:=abs(x-y);
if a[i]>max then max:=a[i];
end;
close(f);
end;
procedure xuly;
begin
l[1]:=1; l[2]:=2;
c[1]:=1;
tmp:=1;
hold:=2;
w:=2;
while w=a[i] then begin writeln(f,j); break; end;
close(f);
end;
begin
nhap;
xuly;
xuat;
end.
Đề bài: http://vn.spoj.com/problems/VOMARIO/
Thuận toán: Sử dụng Interval Tree để quản lí tập các đoạn thẳng. Có thể dễ dàng tìm được công thức QHĐ O(N^2) với F(i) = số năng lượng max đến lượt chơi thứ i. Để giảm độ phức tạp thì có thể dùng IT để cập nhật nhanh.
Code:
#include
#define FORE(i, a, b) for(int i = a; i <= b; i++)
#define FORD(i, a, b) for(int i = a; i >= b; i--)
#define FOR(i, a, b) for(int i = a; i < b; i++)
const int MAXN = 1e5 * 2;
const int INF = 1e9 + 7;
using namespace std;
int n;
long long x[MAXN], w[MAXN], e[MAXN], a[MAXN], v[MAXN], b[MAXN];
long long f[MAXN];
struct line{
long long a, b;
} it[MAXN * 4];
long long Get(line d, long long pos)
{
return d.a * v[pos] + d.b;
}
long long query(int x, int l, int r, long long pos)
{
//cout << it[x].a<<" "< r) return 0;
long long ans = Get(it[x], pos);
if (l == r) return ans;
int mid = (l + r) / 2;
ans = max(ans, query(2 * x, l, mid, pos));
ans = max(ans, query(2 * x + 1, mid + 1, r, pos));
return ans;
}
void update(int x, int l, int r, int u, int v, line val)
{
int mid = (l + r) / 2;
if (r < u || v < l) return;
if (u <= l && r <= v){
// do something
if (Get(it[x], l) >= Get(val, l) && Get(it[x], r) >= Get(val, r)){
return;
}
if (Get(it[x], l) <= Get(val, l) && Get(it[x], r) <= Get(val, r)){
it[x] = val;
return;
}
if (Get(it[x], l) >= Get(val, l) && Get(it[x], mid) >= Get(val, mid)){
update(2 * x + 1, mid + 1, r, u, v, val);
return;
}
if (Get(it[x], l) <= Get(val, l) && Get(it[x], mid) <= Get(val, mid)){
update(2 * x + 1, mid + 1, r, u, v, it[x]);
it[x] = val;
return;
}
if (Get(it[x], mid + 1) >= Get(val, mid + 1) && Get(it[x], r) >= Get(val, r)){
update(2 * x, l, mid, u, v, val);
return;
}
if (Get(it[x], mid + 1) <= Get(val, mid + 1) && Get(it[x], r) <= Get(val, r)){
update(2 * x, l, mid, u, v, it[x]);
it[x] = val;
return;
}
}
update(2 * x, l, mid, u, v, val);
update(2 * x + 1, mid + 1, r, u, v, val);
}
map M;
long long pos[MAXN];
void trau()
{
f[0] = 0;
FORE(i, 1, n) FORE(j, 0, i - 1) if (f[j] >= w[j] * abs(x[i] - x[j]))
f[i] = max(f[i], f[j] - w[j] * abs(x[i] - x[j]) + e[i]);
cout << f[n] << endl;
//FORE(i, 1, n) cout << f[i]<<" ";cout<> n;
FORE(i, 1, n){
cin >> x[i] >> w[i] >> e[i];
a[i] = x[i];
}
//trau();
sort(a, a + n + 1);
FORE(i, 0, n) b[i] = lower_bound(a, a + n + 1, x[i]) - a;
FORE(i, 0, n) v[b[i]] = x[i], M[x[i]] = b[i];
FORE(i, 0, n) pos[i] = M[a[i]];
int top = *max_element(b, b + n + 1);
FORE(i, 1, MAXN * 4 - 1) it[i].a = 0, it[i].b = 0;
update(1, 0, top, 0, top, (line){0, 0});
//FORE(i, 1, n + 1) cout << b[i] <<" "<
Đề bài: http://vn.spoj.com/problems/VODIVIDE/
Thuật toán: Bài này có thể giải bằng phương pháp Quy hoạch động hoặc CTDL Heap. Ở đây giải theo phương pháp Quy hoạch động.
F[i,j]:=max(f[i-1,j],f[i-1,j-1]+b[i]);
Code:
uses math;
const fi='';
fo='';
maxn=5000+2;
var f:array[0..maxn,0..maxn] of longint;
a,b,cs:array[1..maxn] of longint;
res:array[1..maxn] of longint;
dem,n,i,j:Longint;
free:array[1..maxn] of boolean;
procedure nhap;
begin
assign(input,fi);reset(Input);
readln(n);
for i:=1 to n do read(a[i]);
for i:=1 to n do read(b[i]);
close(input);
end;
procedure init;
begin
for i:=1 to n do cs[i]:=i;
end;
procedure swap(var x,y:longint);
var w:longint;
begin
w:=x;x:=y;y:=w;
end;
procedure qs(l,r:longint);
var i,j,x:longint;
begin
i:=l;j:=r;
x:=a[(l+r) div 2];
repeat
while xa[j] do dec(j);
if i<=j then
begin
swap(a[i],a[j]);
swap(b[i],b[j]);
swap(cs[i],cs[j]);
inc(i);dec(j);
end;
until i>j;
if il then qs(l,j);
end;
procedure xuly;
begin
{f[1,0]:=b[1];}
qs(1,n);
for i:=2 to n do
for j:=1 to i div 2 do
begin
f[i,j]:=max(f[i-1,j],f[i-1,j-1]+b[i]);
end;
end;
procedure trace;
begin
i:=n; j:=n div 2;
while (i<>0) and (j<>0) do
begin
if f[i,j]=f[i-1,j-1]+b[i] then
begin
inc(dem);
res[dem]:=i;
free[i]:=true;
dec(i);dec(j);
end else dec(i);
end;
end;
procedure inkq;
begin
assign(output,fo);rewrite(output);
writeln(f[n,n div 2]);
for i:=1 to dem do
begin
for j:=res[i]-1 downto 1 do
if free[j]=false then
begin
write(cs[j],' ');
free[j]:=true;
break;
end;
write(cs[res[i]],' ');
writeln;
end;
close(output);
end;
begin
nhap;
init;
xuly;
trace;
inkq;
end.
Đề bài: http://vn.spoj.com/problems/VOMOVREC/
Thuật toán: Ta sẽ tìm kiếm nhị phân kết quả của bài toán. Với mỗi giá trị chia nhị phân V, ta sẽ “nở” các hình chữ nhật ra về bốn phía một độ dài bằng V. Lúc này điều kiện cần và đủ để tất cả các hình chữ nhật ban đầu có thể di chuyển với khoảng cách không quá V thỏa mãn yêu cầu là tất cả các hình chữ nhật đã được nở có phần giao. Điều kiện N hình chữ nhật có phần giao chung hay không là max(X1) < min(X2) và max(Y1) < min(Y2).
Code:
uses math;
const
fi='';//vomovrec.inp';
fo='';//vomovrec.out';
maxn=trunc(1e6);
oo=trunc(1e9)*3;
type
rect = record
x1,y1,x2,y2 : int64;
end;
var
m,n,i,j : longint;
a : array[1..maxn] of rect;
d,c,g : int64;
function ok(k : int64) : boolean;
var i : longint;
x,y,u,v : int64;
begin
x := a[1].x1 - k;
y := a[1].y1 - k;
u := a[1].x2 +k;
v := a[1].y2 + k;
for i := 2 to n do
with a[i] do
begin
x := max(x, x1-k);
y := max(y, y1-k);
u := min(u, x2+k);
v := min(v, y2+k);
end;
if (xc) and (g<>d) do
begin
if ok (g) then c := g else d := g;
g := (d+c) div 2;
end;if ok(d) then
begin
write(d);
exit;
end;
writeln(c);
close(input);
close(output);
end.
Copyright © 2026 · Genesis Framework · WordPress · Log in
Recent Comments