首页 > 试题广场 >

找出最接近的对称数字

[编程题]找出最接近的对称数字
  • 热度指数:2821 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

输入一个正整数的字符串,输出与它最接近的对称数字(不包括它自己)的字符串

注1: 输入字符串的长度最多不会超过18

注2: 当大于输入数字和小于输入数字的对称数字与输入数字距离相同时,取小的数字作为答案 


输入描述:
输入为一个正整数的字符串


输出描述:
输出为与输入数字最接近的对称数字(不包括输入本身)的字符串
示例1

输入

123

输出

121
最接近的数一定在这三个中产生,首先自身截半,取左边部分,记得half,数据1为half对称复制(如果对称复制后和原数相同则排除掉,2,half-1对称复制,half+1对称复制,另外要注意处理掉加1减1导致位数变化的情况
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;


public class Main {


    public static void main(String[] args) {
        Main da = new Main();
      
            Scanner scanner = new Scanner(System.in);
            String s = scanner.next();
            String duichen = da.duichen(s);
            System.out.println(duichen);
      
    }

    /**
     * 判断一个字符串是否对称
     * @param s 字符串
     * @return 是否对称
     */
    public boolean isRever(String s) {
        char[] arr = s.toCharArray();
        //以0结尾肯定不对称
        if (arr[arr.length - 1] == '0') {
            return false;
        }
        String s2 = new StringBuilder(s).reverse().toString();
        return s.equals(s2);
    }

    public String duichen(String s) {
        Set<Long> tmpSet = new HashSet<Long>();
        long data = Long.parseLong(s);
        char[] arr = s.toCharArray();
        if (arr.length == 1) {
            long res = data == 0 ? 0 : data - 1;
            return String.valueOf(res);
        } else {
            //奇数位
            boolean isJiSu = arr.length%2 != 0 ? true: false;// 是否是奇数位
            boolean isFrontChange = isJiSu, isAfterChange=isJiSu;
            int middle = isJiSu ? 1 : 0;// 如果是奇数位,加上中间数,偶数位不加
                String halfStr = s.substring(0, arr.length / 2 + middle);
                long frontHalf = Long.parseLong(halfStr) - 1;
                // 如果是10,1000,100111之类,减一后位数变化
                boolean isChange = is100(halfStr);
                String frontHalfStr = String.valueOf(frontHalf);
                if (isChange) {
                    isFrontChange = !isJiSu;//位数发生变化,奇变偶偶变奇
                    //偶变奇要补中间9;
                    if (isFrontChange) {
                        frontHalfStr = frontHalfStr+"9";
                    }
                }
                String frontRevStr = copyRever(frontHalfStr, isFrontChange);
                tmpSet.add(Long.parseLong(frontRevStr));
                long afterHalf = Long.parseLong(halfStr) + 1;
                //如果是99,9999, 99999之类, 加1后位数变化 99 9
                isChange = is99(halfStr);//10 : 101
                String afterHalfStr = String.valueOf(afterHalf);
                if (isChange) {
                    isAfterChange = !isJiSu;
                    if (isAfterChange) {
                        afterHalfStr = afterHalfStr.substring(0, afterHalfStr.length()-1);//减一位0
                    }
                }


                String afterRevStr = copyRever(afterHalfStr, isAfterChange);
                tmpSet.add(Long.parseLong(afterRevStr));
                if (!isRever(s)) {
                    String revStr = copyRever(halfStr, isJiSu);
                    tmpSet.add(Long.parseLong(revStr));
                }


        }
        String tmpKey = "";
        long tmp = Long.parseLong(s);
        for (Long cur : tmpSet) {
            long abs = Math.abs(Long.parseLong(s) - cur);
            if (tmp > abs) {
                tmp = abs;
                tmpKey = cur.toString();
            }
        }
        return tmpKey;
    }

    private boolean is99(String half) {
        long halfInt = Long.parseLong(half) + 1;
        return String.valueOf(halfInt).length() != half.length();
    }

    private boolean is100(String half) {
        if (half.equals("1")) {
            return true;
        }
        long halfInt = Long.parseLong(half) - 1;
        return String.valueOf(halfInt).length() != half.length();
    }

    public String copyRever(String half, boolean isMiddle) {
        if (isMiddle) {
            String tmp = half.substring(0, half.length() - 1);
            String rev = new StringBuilder(tmp).reverse().toString();
            return half + rev;
        } else {
            String rev = new StringBuilder(half).reverse().toString();
            return half + rev;
        }

    }

}


发表于 2022-07-13 01:14:27 回复(0)
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String num = sc.next();
        int chang = num.length();
        char[] ch =num.toCharArray();
        if(chang==1) System.out.println(Integer.parseInt(num)-1);
        else if(!sw(num)){
            int left = 0;
            int right = num.length()-1;
            while(left<=right){
                ch[right] = ch[left];
                left++;
                right--;
            }
            System.out.println(String.valueOf(ch));
        }
        else{
            int i=-1;
            int j=1;
            int nu = Integer.parseInt(num);
            while(true){
                int nu1 = nu+i;
                int nu2 = nu+j;
                if(sw(String.valueOf(nu1))) {
                    nu=nu1;
                    break;
                }
                if(sw(String.valueOf(nu2))) {
                    nu=nu2;
                    break;
                }
                i--;
                j++;
            }
            System.out.println(String.valueOf(nu));
        }
    }
    static boolean sw(String str){
        int left = 0;
        int right = str.length()-1;
        while(left<=right){
            if(str.charAt(left)!=str.charAt(right)){
                return false;
            }
            left++;
            right--;
        }
        return true;
    }
}

发表于 2021-10-28 01:55:42 回复(0)
简单粗暴的解法,判断是否为奇偶数 奇数则取 前端值 中间值 后端值  偶数则分前后两段进行判断;
判断逻辑:初选对称数字 然后选取上下限度的值进行取值判断
public class Main {
    public static long getResultNum(String str) {
        long strLong = 0;
        try {
            strLong = Long.valueOf(str);
        } catch (Exception e) {
            return strLong;
        }

        int len = str.length();
        if (len < 2) {
            return strLong - 1;
        }
        long result = 0;
        /*前半段数据*/
        String topVal = null;
        /*中间的数据*/
        String midVal = null;
        /*后半段数据*/
        String downVal = null;
        if (len % 2 == 0) {
            /*偶位数*/
            topVal = str.substring(0, len / 2);
            downVal = str.substring(len / 2, len);
            /*根据topVal获取对称数据*/
            String tempStr = reverseVaule(topVal, null);
            /*组装成完整对称数据*/
            Long resutTemp = Long.valueOf(topVal + tempStr);
            /*处理边接问题*/
            if (resutTemp > strLong) {
                long topLong = Long.valueOf(topVal) - 1;
                /*向下取整*/
                if (String.valueOf(topLong).length() < len / 2) {
                    String resultTemp2 = "";
                    for (int i = 0; i < str.length() - 1; i++) {
                        resultTemp2 = resultTemp2 + "9";
                    }
                    result = Long.valueOf(resultTemp2);
                } else {
                    String reverseVaule = topLong + reverseVaule(topLong + "", null);
                    result = strLong - (Long.valueOf(reverseVaule)) > (resutTemp - strLong) ? resutTemp : Long.valueOf(reverseVaule);
                }

            } else {
                /*向上取整*/
                long topLong = Long.valueOf(topVal) + 1;
                if (String.valueOf(topLong).length() > len / 2) {
                    /*c长度超出则说明超出边界*/
                    result = Long.valueOf(str) + 2;
                } else {
                    String reverseVaule = topLong + reverseVaule(topLong + "", null);
                    result = (Long.valueOf(reverseVaule) - strLong) >= (strLong - resutTemp) ? resutTemp : Long.valueOf(reverseVaule);
                }
            }

        } else {
            /*奇数*/
            topVal = str.substring(0, len / 2);
            midVal = String.valueOf(str.charAt((len / 2)));
            downVal = str.substring(len / 2 + 1, len);
            /*获取对称数据*/
            Long temp1 = Long.valueOf(topVal);
            Long temp2 = Long.valueOf(topVal + midVal);
            Long temp3 = Long.valueOf(downVal);
            String resultTemp = topVal + reverseVaule(topVal, midVal);
            if (Long.valueOf(resultTemp) >= strLong) {
                /*向下取整*/
                --temp2;
                if (String.valueOf(temp2).length() < (topVal + midVal).length()) {
                    String reuslt1 = "9";
                    for (int i = 0; i < String.valueOf(temp3).length(); i++) {
                        reuslt1 = reuslt1 + "9";
                    }
                    result = Long.valueOf(reuslt1);
                } else {
                    String stemp = String.valueOf(temp2);
                    String topValTemp = stemp.substring(0, len / 2);
                    String midValTemp = String.valueOf(stemp.charAt((len / 2)));
                    String resultTemp2 = topVal + reverseVaule(topValTemp, midValTemp);
                    if (Long.valueOf(resultTemp) == strLong) {
                        if (String.valueOf(Long.valueOf(topVal + midVal) + 1).length() > (topValTemp + midValTemp).length()) {
                            result = strLong += 2;
                        } else {
                            result = Long.valueOf(resultTemp2);
                        }
                    } else {
                        result = Long.valueOf(resultTemp) - strLong >= strLong - Long.valueOf(resultTemp2) ? Long.valueOf(resultTemp2) : Long.valueOf(resultTemp);
                    }
                }

            } else {
                /*向上取整*/
                ++temp2;
                if (String.valueOf(temp2).length() > (topVal + midVal).length()) {
                    result = ++temp2;
                } else {
                    String stemp = String.valueOf(temp2);
                    String topValTemp = stemp.substring(0, len / 2);
                    String midValTemp = String.valueOf(stemp.charAt((len / 2)));
                    String resultTemp2 = topVal + reverseVaule(topValTemp, midValTemp);
                    result = Long.valueOf(resultTemp2) - strLong >= strLong - Long.valueOf(resultTemp) ? Long.valueOf(resultTemp) : Long.valueOf(resultTemp2);
                }
            }

        }
        return result;
    }

    public static String reverseVaule(String str, String minStr) {
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(str);
        /*直接反转*/
        String reverseTemp = null;
        if (minStr == null) {
            reverseTemp = stringBuffer.reverse().toString();
        } else {
            reverseTemp = minStr + stringBuffer.reverse().toString();
        }
        return reverseTemp;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        String s = bufferedReader.readLine();
        System.out.printf(Main.getResultNum(s)+"");

    }
}


编辑于 2021-07-18 01:48:10 回复(0)
思路:取一半长度后面加零,形成一个数。比如数值是145821,得到数145000,来生成145000,146000,144000这三个数的对称数值,145541,146641,144441。再计算最小间隔。
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()){
            String s=sc.next();
            long n=Long.parseLong(s);
            long m=(long)Math.pow(10, s.length()/2);
            long k=n-n%m;
            if(k==10)
                m=1;
            long n1=solve(k+m);
            long n2=solve(k);
            long n3=solve(k-m);

            if(n2==n) {
                System.out.println(n2-n3<=n1-n2?n3:n1);
            }else if(n2<n){
                System.out.println(n-n2<=n1-n?n2:n1);
            }else {
                System.out.println(n-n3<=n2-n?n3:n2);
            }
        }
        sc.close();
    }
   private static long solve(long m) {
		String s=Long.toString(m);
		StringBuilder sb=new StringBuilder();
		sb.append(s.substring(0, s.length()/2));
		String tmp=sb.reverse().toString();
		tmp=s.substring(0, s.length()-s.length()/2)+tmp;
		return Long.parseLong(tmp);
	}
}


发表于 2021-03-22 22:39:01 回复(0)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Collections;
public class Main {
    /**
     * 思路
     * 分为数字对称与非对称
     * 
     * 对称要注意取的值要与自己的差值最小
     * 
     * 非对称的数字直接去取对半反转拼接
     *
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s = br.readLine();
        long l = Long.parseLong(s);
        StringBuffer sb1 = new StringBuffer();
        StringBuffer sb2 = new StringBuffer();
        StringBuffer rel = new StringBuffer();
        // 取数字中位数
        int halfLength = s.length() / 2;
        // 前半段放入到sb1中2
        for (int i = 0; i < halfLength; i++) {
            sb1.append(s.charAt(i));
        }
        sb2.append(sb1);
        // 如果是奇数个数字
        if (s.length() % 2 == 1) {
            sb2.append(s.charAt(halfLength));
            rel.append(sb2);
            rel.append(sb1.reverse());
        } else {
            // 偶数个数字,分情况讨论,分别求出上限、下限、中限    1921
            long smallerLeft = (Long.parseLong(sb2.toString()) - 1);  //18
            long biggerLeft = Long.parseLong(sb2.toString()) + 1;  //20
            long midLeft = Long.parseLong(sb2.toString());  //19
            // 1881
            StringBuffer smaller = new StringBuffer();
            smaller.append(smallerLeft);
            StringBuffer s1 = new StringBuffer(smaller);
            smaller.append(s1.reverse());
            long l1 = l - Long.parseLong(smaller.toString());
            //20021
            StringBuffer bigger = new StringBuffer();
            bigger.append(biggerLeft);
            StringBuffer s2 = new StringBuffer(bigger);
            bigger.append(s2.reverse());
            long l2 = Long.parseLong(bigger.toString()) - l;
            //1991
            StringBuffer mid = new StringBuffer();
            mid.append(midLeft);
            StringBuffer s3 = new StringBuffer(mid);
            mid.append(s3.reverse());
            long ll2 = l - Long.parseLong(mid.toString());
            long ll1 = Long.parseLong(mid.toString()) - l;
            long l3 = ll1 >= 0 ? ll1 : ll2;
            // 比较差距最小值
            Long[] arr = {l1, l2, l3};
            Long min = Collections.min(Arrays.asList(arr));
            if (l1 == min) {
                rel.append(smaller);
            } else if (l2 == min) {
                rel.append(bigger);
            } else {
                rel.append(mid);
            }
        }
        System.out.println(rel.toString());
    }
}

兴业银行笔试时碰到这题,现在写出来了

发表于 2020-11-12 15:04:44 回复(0)
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;

public class Main {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        char[] carr = sc.nextLine().toCharArray();
        
        int mid=(carr.length+1)/2-1;
        int i;
        for(i=mid+1;i<carr.length;i++) {
            carr[i]=carr[carr.length-i-1];
            
            
            
        }
        for(i=0;i<carr.length;i++)
        System.out.print(carr[i]);
    
    }
    

        

    
    
    
}
发表于 2020-06-06 19:45:20 回复(0)