Nguồn đề bài: http://www.spoj.com/PTIT/problems/P151PROG/
1. Đề bài P151PROG spoj PTIT
Trong giờ ăn trưa tại Học viên Công nghệ Bưu chính Viễn thông, có n sinh viên đang xếp hang để lấy đồ.
Cảm thấy chán vì phải đứng đợi một mình, vì vậy mỗi sinh viên viết ra mã sinh viên của mình đứng ngay trước và ngay sau của mình. Nếu không có ai đứng trước hoặc không có ai đứng sau thì viết ra 0.
Đột nhiên, xe chở nước sôi đi qua, tất cả sinh viên phải tránh. Khi họ trở lại, họ không nhớ vị trí của mình mà chỉ nhớ mã sinh viên của người đừn trước và người đứng sau.
Hãy giúp các sinh viên PTIT tìm lại vị trí của mình!!!!
Input
Dòng đầu tiên gồm số tự nhiên n (2 ≤ n ≤ 2·10^5) – số lượng sinh viên.
n dòng tiếp theo, dòng thứ i gồm cặp số tự nhiên ai, bi (0 ≤ ai, bi ≤ 10^6), với ai là mã sinh viên của người đứng trước, bi là mã sinh viên của người đứng sau 1 sinh viên nào đó. Nếu không có ai đứng trước hoặc không có ai đứng sau nhập 0.
Mã sinh viên của mỗi sinh viên là khác nhau.
Output
Trên 1 dòng, in ra n số x1, x2, …, xn , danh sách của các sinh viên theo thứ tự ban đầu.
Example
Input:
4
92 31
0 7
31 0
7 141
Output:
92 7 31 141
2. Hướng dẫn P151PROG spoj PTIT
Nhận Xét:
– Đề bài cho ta biết “Nếu không có ai đứng trước nhập 0” vậy có nghĩa ta sẽ xác định được kết quả ở vị trí thứ 2. tạm gọi số này là “số đầu tiên” đi.
Hướng dẫn:
– Từ nhận xét trên ta có thể tính được các vị trí 2, 4, 6, 8, ….. n
– Từ số đầu tiên, ta thực hiện chặt nhị phân tìm số trong dãy A[i] ( lưu ý là phải sort A, và B theo A truoc), gọi k là vị trí tìm thấy. rồi ghi kq vào vị trí 4, rồi tiếp tục lấy B[k] làm mốc xong rồi chặt rồi ghi vào vị trí 6, tương tự….8,…10,…n.. dừng lại khi k=0.
– Tương tự từ gợi ý trên bạn có thể dễ dàng tìm kết quả cho các vị trí 1, 3, 5, …..
* Thật ra lúc làm bài này mình quên việc có thể dùng mảng đánh dấu. nên các ban có thể dùng mảng đánh dấu. mà ko cần SORT và chặt nhị phân. code tham khảo mình viết theo ý tưởng chặt nhị phân. các bạn có thể code lại bằng đánh dấu sẽ dễ hơn…
####
Gợi ý của bạn Trình Gia Lạc:
“có 2 thằng suất hiện 1 lần trong đó thằng nào ở bên trái thì là đầu tiên, thằng thứ 2 là thằng đứng R trong cặp (0, R), từ 2 thằng này suy luận ra tắt cả thằng còn lại: 1->3, 2 -> 4 ,…”
Lời giải từ BTC
Phân dãy sinh viên thành 2 dãy, một dãy là các sinh viên đứng ở vị trí chẵn, một dãy là các sinh viên đứng ở vị trí lẻ, sau đó gộp dãy.
Có thể xây dựng dãy các sinh viên ở vị trí lẻ bằng cách “nhảy” từ người có a = 0.
Dãy các sinh viên ở vị trí chẵn có thể xây dựng bằng phương pháp tương tự.
3. Code Tham khảo P151PROG spoj PTIT
const fi=''; nmax=2*100000; type data=longint; var f:text; A,B,kq:array[0..nmax+1] of data; n,sodau,so1,so2:data; so:array[0..1000000] of data; procedure sort(l,r: longint); var i,j,x,y: longint; begin i:=l; j:=r; x:=a[(l+r) div 2]; repeat while a[i]<x do inc(i); while x<a[j] do dec(j); if not(i>j) then begin y:=a[i]; a[i]:=a[j]; a[j]:=y; y:=b[i]; b[i]:=b[j]; b[j]:=y; inc(i); j:=j-1; end; until i>j; if l<j then sort(l,j); if i<r then sort(i,r); end; procedure docfile; var i,j,dem:data; begin assign(f,fi); reset(f); readln(f,n); fillchar(so,sizeof(so),0); for i:=1 to n do begin readln(f,a[i],b[i]); so[a[i]]:=so[a[i]] xor 1; so[b[i]]:=so[b[i]] xor 1; end; for i:=0 to 1000000 do if so[i]<>0 then begin so1:=i; for j:=i+1 to 1000000 do if so[j]<>0 then begin so2:=j; break; end; break; end; close(f); end; function tknpA(x:data):data; var dau,cuoi,giua:data; begin dau:=1; cuoi:=n; while dau<=cuoi do begin giua:=(dau+cuoi) div 2; if A[giua]=X then exit(giua) else if x>a[giua] then dau:=giua+1 else cuoi:=giua-1; end; exit(0); end; procedure xuli; var i,j,x,dem,vt:data; begin sort(1,n); if tknpA(so1)<>0 then sodau:=so1 else sodau:=so2; //////////////// x:=B[1]; kq[2]:=x; dem:=2; repeat vt:=tknpA(x); if vt<=1 then break; inc(dem,2); kq[dem]:=B[vt]; x:=B[vt]; until false; x:=sodau; kq[1]:=x; dem:=1; repeat vt:=tknpA(x); if vt<=1 then break; inc(dem,2); kq[dem]:=B[vt]; x:=B[vt]; until false; for i:=1 to n do write(kq[i],' '); end; begin docfile; xuli; end.
Chào bạn,
Ảnh mịnh hoạ test bị lỗi, bạn vui lòng bổ sung lại nhé. Cám ơn nhiều
Ảnh này mình upload lên google mà không hiểu sao bị xóa, mình tìm lại trong PTIT cũng bị xóa luôn. bạn thông cảm nha, mình không có lưu lại trên máy 🙁
Tuy nhiên minh họa cho test này lần lượt là :
92
7
31
141
thôi bạn, chứ hk có gì đặc biệt 🙂
Cám ơn bạn.