Nguồn đề bài: http://www.spoj.com/PTIT/problems/P152PROF/
1. Đề bài P152PROF PTIT spoj
Cho số tự nhiên m và số nguyên s không âm. Nhiệm vụ của bạn là tìm số bé nhất và lớn nhất có m chữ số và tổng chữ số bằng s.
Input
Dòng đầu gồm 2 số m và s (1 ≤ m ≤ 100, 0 ≤ s ≤ 900).
Output
In ra kết quả của bài toán.
Số đầu tiên là số bé nhất, số thứ hai là số lớn nhất. Nếu không có đáp án in ra “-1 -1”.
Example
Input:
2 15
Output:
69 96
2. Hướng dẫn P152PROF PTIT spoj
Mình sẽ hướng dẫn các bạn giải từng tình huống sau:
– Nếu m=1 và s=0 thì kết quả là “0 0”.
– Tiếp tục, dễ dàng nhận thấy khi s=0 hoặc s>9*m thì kết quả sẽ cho ra một số vô nghĩa nên lúc này kết quả sẽ là “-1 -1”.
– Tìm số lớn nhất có tổng các chữ số bằng S:
+ Ưu tiên điền các số lớn nhất còn có thể điền vào các vị trí đầu tiên. các số lớn nhất đó có thể là [0..9] và nó phụ thuộc vào S còn lại, mỗi lần điền như vậy cập nhật lại s còn lại. khi điền hết thì cho những số cuối cùng chưa điền bằng 0. Nhận thấy với cách làm này ta luôn thu được 1 số có nghĩa vì các số 0 luôn ở phía sau.
– Tìm số nhỏ nhất có tổng các chữ số bằng S:
+ việc tìm số nhỏ nhất có thể dựa trên kết quả của số lớn nhất đã tìm được ở trên.
+ ở đây rất dễ sai vì nó còn xét đến chữ số có nghĩa. bạn dễ dàng nhận thấy nếu lật ngược kết quả lớn nhất tìm được ở trên thì sẽ cho ra số nhỏ nhất (và khả năng có chữ số vô nghĩa).
+ Cách xử lí: Nếu chữ số đầu tiên sau khi lật ngược xâu kết quả lớn nhất mà bằng 0 thì mình sẽ cho nó bằng 1. và đi tìm 1 vị trí khác có chữ số khác 0, giảm nó xuống 1 đơn vị là xong.
– Xuất ra KQ bài toán
3. code tham khảo P152PROF PTIT spoj
const fi='';
nmax=100;
type data=longint;
var
f:text;
m,s:data;
A:array[0..nmax+1] of data;
procedure xuli;
var i,j,stam:data;
begin
if (m=1) and (s=0) then
begin
writeln('0 0');
exit;
end;
if (s>9*m) or (s=0) then
begin
writeln('-1 -1');
exit;
end;
// tim so nho nhat.
stam:=s;
for i:=1 to m do a[i]:=0;
for i:=m downto 1 do
begin
for j:=9 downto 0 do
if stam-j>=0 then
begin
a[i]:=j;
stam:=stam-j;
break;
end;
if a[i]=0 then break;
end;
if a[1]=0 then
begin
A[1]:=1;
for j:=2 to m do
if a[j]<>0 then
begin
a[j]:=a[j]-1;
break;
end;
end;
for i:=1 to m do
write(a[i]);
write(' ');
// tim so lon nhat.
stam:=s;
for i:=1 to m do A[i]:=0;
for i:=1 to m do
begin
for j:=9 downto 0 do
if stam-j>=0 then
begin
A[i]:=j;
stam:=stam-j;
break;
end;
if A[i]=0 then break;
end;
for i:=1 to m do
write(a[i]);
end;
begin
assign(f,fi); reset(f); readln(f,m,s); close(f);
xuli;
end.