Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 54 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
54
Dung lượng
783,46 KB
Nội dung
Chương Luyện tập từ đề thi 5.1 Số nguyên tố độ cao Olimpic Duy Tân 2009 Độ cao số tự nhiên tổng chữ số số Với cặp số tự nhiên n h cho trước liệt kê số ngun tố khơng vượt q n có độ cao h, 10 n 1000000; h 54 hprimes.inp n h hprimes.out dòng số Dữ liệu test n = 1000, h = 16 Kết 15 số nguyên tố độ cao 16: 79, 97, 277, 349, 367, 439, 457, 547, 619, 673, 691, 709, 727, 853, 907 Thuật toán Thuật toán liệt kê số nguyên tố độ cao h khoảng n Gọi thủ tục Sang(n) (do Eratosthenes đề xuất, xem Tập 2) xác định số nguyên tố khoảng n đánh dấu vào mảng byte p: p[i] = i số nguyên tố Duyệt lại số nguyên tố i danh sách p, tính độ cao số i Nếu Height(i) = h ghi nhận end Để tính độ cao số i ta tách dần chữ số hàng đơn i phép chia dư cho 10 cộng dồn vào biến tổng Độ phức tạp Thủ tục sàng duyệt phép gán) n lần, lần lại duyệt n phần tử cần cỡ n n thao tác sở (phép nhân, Chương trình (* Hprimes.pas – So nguyen to cung cao *) uses crt; const fn = 'hprimes.inp'; gn = 'hprimes.out'; nl = #13#10; bl = #32; mn = 1000000; type mb1 = array[0 mn] of byte; var p: mb1; n,h: longint; procedure Sang(n: longint); var i,j: longint; begin fillchar(p,sizeof(p),0); for i := to round(sqrt(n)) if (p[i] = 0) then for j := i to (n div i) p[i*j] := 1; end; function Height(x: longint): integer; var sum : integer; begin sum := 0; while x begin sum := sum + (x mod 10); x := x div 10; end; Height := sum; end; procedure Ghi; var i: longint; G: text; begin assign(g,gn); rewrite(g); for i := to n if p[i] = then if Height(i) = h then writeln(g,i); close(g); end; procedure Doc; var f: text; begin assign(f,fn); reset(f); readln(f,n,h); close(f); end; BEGIN Doc; Sang(n); Ghi; writeln(nl,' Fini'); readln; END // DevC++: hprimes.cpp - So nguyen to cung cao #include #include #include #include #include using namespace std; // D A T A A N D V A R I A B L E const int mn = 1000001; char p[mn]; int n, h; const char * fn = "hprimes.inp"; const char * gn = "hprimes.out"; // P R O T O T Y P E S void Doc(); void Sang(); void Ghi(); int Height(int x); // I M P L E M E N T A T I O N int main() { Doc(); Sang(); Ghi(); cout h; f.close(); } // Sang Eratosthenes void Sang() { // p[i] = i nguyen to int can = (int) sqrt(n); int i, j, ni; memset(p,0,sizeof(p)); for (i = 2; i n) { manh = 2; j -= n; } if (i > n) { manh += 1; i -= n; } v += manh * d; d *= 4; } return v; } // Cho vi tri o tren cot v, tinh toa (i,j) n = 2^k void ToaDo(int k, int v, int &i, int &j) { int n = 1, d = >= 2; // d /= 4; manh = (v - 1) / d; if (manh >= 2) j += n; if (manh % == 1) i += n; v -= manh * d; n *= 2; } } Độ phức tạp Với n = 2k chương trình cần k lần lặp, lần lặp cần thực khơng q 10 phép tốn số học số nguyên Thủ tục Test hiển thị vị trí v (i,j), i = n, j = n sau xuất phát từ vị trí v để tính lại tọa độ i, j (* Pascal *) procedure Test(k: integer); var n, v, ii, jj : integer; begin n := shl k; { n = 2^k } writeln; writeln( ' k = ', k, ' n = ', n); for i := to n for j := to n begin v := ViTri(k, i, j); ToaDo(k, v, ii, jj); writeln; write('(',i, ',', j, ') => ', v); writeln(' => ', '(', ii, ',', jj, ')'); readln; end; end; // DevC++ void Test(int k) { int n =