44.回文对称数(重点)

96 阅读5分钟

链接:ac.nowcoder.com/acm/problem…
来源:牛客网

题目描述

今天牛牛学到了回文串,他想在数字里面找回文,即回文数,回文数是正着读与倒着读都一样的数,比如1221,343是回文数,433不是回文数。请输出不超过n的回文数。

输入描述:

输入一个整数n(1 <= n <= 100000)

输出描述:

从1开始按从小到大的顺序输出所有回文数

示例1

输入

10

输出

1
2
3
4
5
6
7
8
9

注意

题目中已经规定了输入的值为正整数,如果没有规定,则需要自己提前判断。

bool solve(string str){
    if(str < 0) return false;
}

解法一:转化为字符串根据双指针来判断

1.我们首先获取一个整数

#include <bits/stdc++.h>

using namespace std;

int main(){
    int n;
    cin >> n;
    return 0; 
}

2.循环遍历,将遍历的每一个数转化为字符串来判断

#include <bits/stdc++.h>

using namespace std;

int main(){
    int n;
    cin >> n;
    for(int i = 1;i <= n;i ++){
        string str = to_string(i);
    }
    return 0; 
}

3.首先定义一个函数,然后定义双指针,一个指向头,另一个指向尾

bool solve(string str){
    int left = 0;
    int right = str.size() - 1;
}

4.定义一个左指针小于等于右指针的循环,我们再判断头和尾是否相等,如果不等返回false

bool solve(string str){
    int left = 0;
    int right = str.size() - 1;
    while(left <= right){
        if(str[left] != str[right])
            return false;
    }
}

5.然后我们以此将左指针右移,右指针左移,以控制循环,最后返回true

bool solve(string str){
    int left = 0;
    int right = str.size() - 1;
    while(left <= right){
        if(str[left] != str[right])
            return false;
            left++;
            right--;
    }
    return true;	
}

6.最后根据solve函数判断来输出回文数的值

int main(){
    int n;
    cin >> n;
    for(int i = 1;i <= n;i ++){
        string str = to_string(i);
        if(solve(str)){
            cout << str << '\n';
        } 
    }
	return 0; 
}

7.完整代码


#include <bits/stdc++.h>

using namespace std;

bool solve1(string str){
   
    int left = 0;
    int right = str.size()-1;
    while(left <= right){
        if(str[left] != str[right]){
            return false;
        }
        left++;
        right--;
    }
    return true;
}

int main(){
    int n;
    cin >> n;
    
    for(int i = 1;i <= n;i ++){
        string str = to_string(i);
        if(solve1(str)){
        cout << i << endl;
        }
    }
   
    return 0;
}

解法二:直接判断正序和倒序的值是否相等

1.我们首先获取一个整数

#include <bits/stdc++.h>

using namespace std;

int main(){
    int n;
    cin >> n;
    return 0; 
}

2.首先定义一个函数,然后定义初始值和翻转值

bool solve(int n){
    int orinum = n;
    int revernum = 0;
}

3.定义一个n不等于0的循环(重要)

  1. 然后取n的个位,
  2. 反转数等于反转数*10+个位
  3. 最后n自除10
bool solve(int n){
    int orinum = n;
    int revernum = 0;
    while(n){
        int g = n % 10;
        revernum = revernum * 10 + g;
        n /= 10;
    }	
}

4.判断反转数和原数是否相等,相等返回true,反之返回false

bool solve(int n){
    int orinum = n;
    int revernum = 0;
    while(n){
        int g = n % 10;
        revernum = revernum * 10 + g;
        n /= 10;
    }	
    if(revernum == orinum) return true;
    else return false;
}

5.完善main函数,根据solve函数来控制循环输出

int main(){
    int n;
    cin >> n;
    for(int i = 1;i <= n;i ++){
        if(solve(i))
        cout << i << '\n';
    }
    return 0; 
}

6.完整代码

#include <bits/stdc++.h>

using namespace std;

bool solve(int n){
    int orinum = n;
    int revernum = 0;
    while(n){
        int g = n % 10;
        revernum = revernum * 10 + g;
        n /= 10;
    }
    if(revernum == orinum) return true;
    else return false;
}

int main(){
    int n;
    cin >> n;
    for(int i = 1;i <= n;i ++){
        if(solve(i))
        cout << i << '\n';
    }

    return 0; 
}

解法三(难):解法二的优化,不利用额外的存储空间,我们只需要判断前一半的数和后一半的数以此来判断是否为回文数

1.我们首先获取整数,然后根据solve函数来判断for循环输出

#include <bits/stdc++.h>

using namespace std;

int main(){
    int n;
    cin >> n;
    for(int i = 1;i <= n;i ++){
        if(solve(i))
        cout << i << '\n';
    }
    return 0; 
}

2.定义一个函数。定义一个反转数用来将后半部分数来反转。反转数初始值为0

bool solve(int n){
    reversum = 0;
  
}

3.定义一个反转数大于原数自除的数,通俗来说,就是后部分的反转数大于前部分的数(重要)。

bool solve(int n){
    int reversum = 0;
    while(reversum > n){
        int g = reversum % 10;
        reversum = reversum * 10 + g;
        n /= 0;
    }
}

4.定义一个反转数大于原数自除,通俗来说,就是后部分的反转数大于前部分的数(重要)。

bool solve(int n){
    reversum = 0;
    while(reversum > n){
        int g = reversum % 10;
        reversum = reversum * 10 + g;
        n /= 0;
    }
}

5.判断反转数是否和原数自除相等,这里有两种情况(重要)。

因为我们判断条件为n > reversum,也就是说n和反转数相等,或者n比反转数小,对应的就是偶数和奇数两种情况

  1. 当输入的数为偶数时,反转数和原数自除相等(n和反转数相等)
bool solve(int n){
    reversum = 0;
    while(reversum > n){
        int g = reversum % 10;
        reversum = reversum * 10 + g;
        n /= 0;
    }
    return reversesum == n;
}
  1. 当输入的数为奇数时,反转数除以十和原数自除相等(n比反转数小)
bool solve(int n){
    reversum = 0;
    while(reversum > n){
        int g = reversum % 10;
        reversum = reversum * 10 + g;
        n /= 0;
    }
    return reversesum / 10 == n;
}
  1. 当奇数和偶数两种情况结合起来
bool solve(int n){
    reversum = 0;
    while(reversum > n){
        int g = reversum % 10;
        reversum = reversum * 10 + g;
        n /= 0;
    }
    return reversesum / 10 == n || reversesum / 10 == n;
}

6.完整代码

#include <bits/stdc++.h>

using namespace std;

bool solve(int n){
	if(n != 0 && n % 10 == 0) return false;
	int reversum = 0;
	while(n > reversum){
		int g = n % 10;
		reversum = reversum * 10 + g;
		n /= 10;
	}
	return reversum == n || reversum / 10 == n ;
}

int main(){
    int n;
    cin >> n;
    for(int i = 1;i <= n;i ++){
        if(solve(i))
                cout << i << '\n';
    }
    return 0; 
}