Số đối xứng là số có thể viết từ trái sang phải các chữ số của nó ta vẫn được ch…
Từ một số có hai chữ số ta có thể nhận được một số đối xứng theo cách sau: lấy số ban đầu cộng
với số ánh xạ gương của nó, tức là số nhận được bằng cách đọc các chữ số từ phải sang trái. Nếu
chưa phải là số đối xứng, số đó lại được cộng với ánh xạ gương của nó và tiếp tục như vậy cho
đến khi nhận được số đối xứng. Ví dụ, từ số 48 ta có 48 + 84 = 132, 132 + 231 = 363. Như vậy
48 tương ứng với 363.
Yêu cầu: Tìm số đối xứng của N (11 N 99).
INPUT
– Chứ một số nguyên dương N duy nhất.
– Dữ liệu đảm bảo luôn tìm được đáp án
OUTPUT: Số đối xứng tương ứng của N.
Ví dụ:
INPUT OUTPUT
48 363
22 22
(làm bằng lập trình c++ ,đang cần gấp mọi người ạ )
Trước tiên, chúng ta cần hiểu rõ bài toán:
– Số đối xứng: Là số đọc xuôi hay ngược đều giống nhau. Ví dụ: 11, 22, 121, 363.
– Ánh xạ gương: Là số thu được bằng cách đảo ngược thứ tự các chữ số của số ban đầu. Ví dụ: ánh xạ gương của 48 là 84, ánh xạ gương của 132 là 231.
– Quy trình tìm số đối xứng: Bắt đầu từ một số N có hai chữ số. Lấy N cộng với ánh xạ gương của nó. Nếu kết quả chưa phải là số đối xứng, ta tiếp tục lấy kết quả đó cộng với ánh xạ gương của nó, và cứ thế lặp lại cho đến khi nhận được số đối xứng.
Yêu cầu của bài toán là tìm số đối xứng cuối cùng khi bắt đầu từ một số N cho trước (với 11 <= N <= 99).
Bây giờ, chúng ta sẽ đi vào chi tiết cách giải bằng lập trình C++.
Bước 1: Phân tích đầu vào và đầu ra
– INPUT: Một số nguyên dương N duy nhất, với điều kiện 11 <= N <= 99.
- OUTPUT: Số đối xứng tương ứng của N.
Bước 2: Xây dựng thuật toán
Chúng ta cần một vòng lặp để thực hiện phép cộng và kiểm tra tính đối xứng lặp đi lặp lại cho đến khi đạt được điều kiện dừng.
1. Kiểm tra xem một số có phải là số đối xứng hay không:
Để kiểm tra một số có phải là số đối xứng hay không, chúng ta cần chuyển số đó thành chuỗi, sau đó kiểm tra xem chuỗi đó có đối xứng hay không.
– Chuyển số \(num\) thành chuỗi \(str_num\).
– Kiểm tra \(str_num\) có đối xứng hay không bằng cách so sánh ký tự ở vị trí \(i\) với ký tự ở vị trí \(length – 1 – i\), với \(i\) chạy từ 0 đến \(length / 2 – 1\). Nếu tất cả các cặp ký tự này bằng nhau, thì số đó là đối xứng.
2. Tìm ánh xạ gương của một số:
Để tìm ánh xạ gương của một số, chúng ta cũng có thể chuyển số đó thành chuỗi, đảo ngược chuỗi, rồi chuyển lại thành số.
– Chuyển số \(num\) thành chuỗi \(str_num\).
– Đảo ngược chuỗi \(str_num\) để được chuỗi \(reversed_str_num\).
– Chuyển \(reversed_str_num\) trở lại thành số nguyên.
3. Vòng lặp chính:
– Bắt đầu với số N ban đầu.
– Trong một vòng lặp \(while\) (hoặc \(do-while\)):
– Kiểm tra xem số hiện tại có phải là số đối xứng hay không. Nếu có, thoát khỏi vòng lặp.
– Nếu chưa phải số đối xứng:
– Tính ánh xạ gương của số hiện tại.
– Cộng số hiện tại với ánh xạ gương của nó để có số mới.
– Cập nhật số hiện tại bằng số mới vừa tính.
– Do đề bài đảm bảo rằng luôn tìm được đáp án, nên vòng lặp này chắc chắn sẽ kết thúc.
Bước 3: Viết mã C++
Chúng ta sẽ cần các thư viện như \(
cpp
#include
#include
#include
// Hàm kiểm tra xem một số có phải là số đối xứng hay không
bool isPalindrome(int n) {
// Chuyển số thành chuỗi
std::string s = std::to_string(n);
// Tạo một chuỗi đảo ngược
std::string reversed_s = s;
std::reverse(reversed_s.begin(), reversed_s.end());
// So sánh chuỗi gốc và chuỗi đảo ngược
return s == reversed_s;
}
// Hàm tìm ánh xạ gương của một số
int getMirrorImage(int n) {
// Chuyển số thành chuỗi
std::string s = std::to_string(n);
// Đảo ngược chuỗi
std::reverse(s.begin(), s.end());
// Chuyển chuỗi đảo ngược trở lại thành số
return std::stoi(s);
}
int main() {
int n; // Biến lưu trữ số ban đầu
// Nhập số N từ bàn phím
std::cin >> n;
// Vòng lặp để tìm số đối xứng
// Sử dụng do-while để đảm bảo vòng lặp chạy ít nhất 1 lần,
// trường hợp N ban đầu đã là số đối xứng.
do {
// Nếu số hiện tại đã là số đối xứng, thoát khỏi vòng lặp
if (isPalindrome(n)) {
break;
}
// Tính ánh xạ gương của số hiện tại
int mirror = getMirrorImage(n);
// Cộng số hiện tại với ánh xạ gương của nó
n = n + mirror;
} while (true); // Vòng lặp vô hạn, sẽ thoát bằng ‘break’
// In ra kết quả là số đối xứng tìm được
std::cout << n << std::endl;
return 0; // Kết thúc chương trình
}
Giải thích chi tiết từng phần của mã:
1. \(#include
2. \(#include
3. \(#include
4. \(bool isPalindrome(int n)\):
– Hàm này nhận vào một số nguyên \(n\).
– \(std::string s = std::to_string(n);\): Chuyển số nguyên \(n\) thành dạng chuỗi. Ví dụ: \(48\) thành \(“48″\).
– \(std::string reversed_s = s;\): Tạo một bản sao của chuỗi \(s\).
– \(std::reverse(reversed_s.begin(), reversed_s.end());\): Sử dụng hàm \(std::reverse\) để đảo ngược nội dung của \(reversed_s\). Nếu \(s\) là \(“48″\), \(reversed_s\) sau khi đảo ngược sẽ là \(“84″\).
– \(return s == reversed_s;\): So sánh chuỗi gốc \(s\) với chuỗi đảo ngược \(reversed_s\). Nếu chúng giống nhau (ví dụ: \(s\) là \(“363″\), \(reversed_s\) cũng là \(“363″\)), hàm trả về \(true\) (đúng là số đối xứng). Ngược lại, trả về \(false\).
5. \(int getMirrorImage(int n)\):
– Hàm này nhận vào một số nguyên \(n\).
– \(std::string s = std::to_string(n);\): Chuyển số nguyên \(n\) thành dạng chuỗi. Ví dụ: \(48\) thành \(“48″\).
– \(std::reverse(s.begin(), s.end());\): Đảo ngược chuỗi \(s\). Nếu \(s\) là \(“48″\), nó sẽ trở thành \(“84″\).
– \(return std::stoi(s);\): Chuyển chuỗi đã đảo ngược trở lại thành một số nguyên và trả về giá trị đó. Ví dụ: chuỗi \(“84″\) sẽ được chuyển thành số nguyên \(84\).
6. \(int main()\):
– \(int n;\): Khai báo một biến \(n\) kiểu số nguyên để lưu trữ số đầu vào và cũng là biến sẽ được cập nhật trong quá trình xử lý.
– \(std::cin >> n;\): Đọc giá trị số nguyên từ bàn phím và gán vào biến \(n\).
– \(do { … } while (true);\): Đây là một vòng lặp \(do-while\). Khối mã bên trong \(do\) sẽ được thực thi ít nhất một lần, sau đó điều kiện \(while(true)\) sẽ được kiểm tra. Vì điều kiện luôn là \(true\), vòng lặp này về lý thuyết là vô hạn. Tuy nhiên, chúng ta sẽ sử dụng lệnh \(break\) để thoát khỏi vòng lặp khi điều kiện dừng (tìm được số đối xứng) được thỏa mãn.
– \(if (isPalindrome(n)) { break; }\): Bên trong vòng lặp, đầu tiên ta kiểm tra xem số \(n\) hiện tại có phải là số đối xứng không bằng cách gọi hàm \(isPalindrome(n)\). Nếu \(isPalindrome\) trả về \(true\), nghĩa là chúng ta đã tìm được số đối xứng, và lệnh \(break;\) sẽ ngắt vòng lặp ngay lập tức.
– \(int mirror = getMirrorImage(n);\): Nếu \(n\) chưa phải là số đối xứng, ta gọi hàm \(getMirrorImage(n)\) để lấy ánh xạ gương của \(n\) và lưu vào biến \(mirror\).
– \(n = n + mirror;\): Thực hiện phép cộng: số \(n\) hiện tại cộng với ánh xạ gương \(mirror\) của nó. Kết quả này sẽ được gán lại vào biến \(n\), chuẩn bị cho lần lặp tiếp theo.
– \(std::cout << n << std::endl;\): Sau khi vòng lặp kết thúc (nhờ lệnh \(break\)), biến \(n\) sẽ chứa số đối xứng cuối cùng. Dòng này sẽ in giá trị của \(n\) ra màn hình, theo sau là ký tự xuống dòng \(std::endl\).
- \(return 0;\): Báo hiệu rằng chương trình đã kết thúc thành công.
Ví dụ minh họa với N = 48:
1. Nhập \(N = 48\).
2. Vòng lặp \(do-while\) bắt đầu.
3. Kiểm tra \(isPalindrome(48)\): \(48\) không phải là số đối xứng (trả về \(false\)).
4. Tính \(mirror = getMirrorImage(48)\): \(48\) -> \(“48″\) -> đảo ngược là \(“84″\) -> \(84\). Vậy \(mirror = 84\).
5. Cập nhật \(n = n + mirror\): \(n = 48 + 84 = 132\).
6. Vòng lặp tiếp tục với \(n = 132\).
7. Kiểm tra \(isPalindrome(132)\): \(132\) không phải là số đối xứng (trả về \(false\)).
8. Tính \(mirror = getMirrorImage(132)\): \(132\) -> \(“132″\) -> đảo ngược là \(“231″\) -> \(231\). Vậy \(mirror = 231\).
9. Cập nhật \(n = n + mirror\): \(n = 132 + 231 = 363\).
10. Vòng lặp tiếp tục với \(n = 363\).
11. Kiểm tra \(isPalindrome(363)\): \(363\) là số đối xứng (trả về \(true\)).
12. Lệnh \(break;\) được thực thi, vòng lặp kết thúc.
13. In giá trị cuối cùng của \(n\), là \(363\).
Bài tập này giúp các em hiểu rõ hơn về cách làm việc với chuỗi trong C++, cách chuyển đổi giữa số và chuỗi, cũng như cách xây dựng một thuật toán lặp để giải quyết vấn đề. Chúc các em học tốt!
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll anhxaguong(ll n)
{
ll s=0;
while(n!=0)
{
s=s*10+n%10;
n/=10;
}
return s;
}
bool sodoixung(ll n)
{
if(anhxaguong(n)==n) return true;
return false;
}
int main()
{
ll n;
cin>>n;
while(!sodoixung(n))
{
n+=anhxaguong(n);
}
cout<<n;
}
#include <iostream>
using namespace std;
bool dx(long long n) {
long long p=n,s=0;
while (p) {
s=s*10+p%10;
p/=10;
}
return s==n;
}
long long dao(long long p) {
long long s=0;
while (p) {
s=s*10+p%10;
p/=10;
}
return s;
}
int main() {
long long n;
cin >> n;
while (!dx(n)) n+=dao(n);
cout << n;
}