zoukankan      html  css  js  c++  java
  • SPOJ #5 The Next Palindrome

    "not more than 1000000 digits" means an efficient in-place solution is needed. My first solution was string<->int conversion based. It worked for small ints, but got TLE with large numbers.

    Thanks to http://www.bytehood.com/spoj-the-next-palindrome/418/ that shed lights on me. The key idea is the same as my first idea: simply keep increasing digits near the center digit(s), and we only need figure out left half of the digits since it is mirrored palindrome. 

    (I saw a lot of rejudge requests in SPOJ comments.. several erroneous results got returned from AC code. Mine's also rejected due to wrong answer - I think rejudge is needed)

    Corner cases are important to this problem: single digits, all 9s, carry-over situation etc. Here is my code:

    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    
    int dCarry = 0;
    int findLgRInx(char *str, int len, int i_l)
    {
        int i_mis = -1;
        int i = i_l;
        while(i-- >= 0)
        {
            if(str[i] > str[len - 1 - i])
            {
                i_mis = i;
                break;
            }
        }
        return i_mis;
    }
    
    void incLHalf(char *str, int len, int i_l)
    {
        int i = i_l;
        while(i >= 0)
        {
            int d = str[i] - '0';
            if(d < 9)
            {
                str[i] = (d + 1) + '0';
                return;
            }
            else
            {
                str[i] = '0';
                if(i > 0)
                {
                    int nd = str[i-1]-'0';
                    if(nd < 9)
                    {
                        str[i-1] = (nd + 1) + '0';
                        return;
                    }                
                }
                else
                {
                    dCarry = 1;
                    return;
                }
            }
            i--;
        }
    }
    
    void copyl2r(char *str, int len, int i_l)
    {
        int i = i_l;
        while(i >= 0)    
        {
            str[len-i-1] = str[i];        
            i--;
        }
    }
    
    void calc_next_palin(char *str)
    {
        unsigned len = strlen(str);
        if(len == 1)        
        {
            int i = atoi(str);
            cout << (i + 1) + i / 9 << endl;
            return;
        }
        
        int i_l = 0, i_r = 0;
        if(len % 2 == 0)
        {
            i_l = len / 2 - 1;
            i_r = len / 2;
            int i_mis = findLgRInx(str, len, i_l);
            if(i_mis != -1)
            {
                copyl2r(str, len, i_mis);
                cout << str << endl; 
                return;
            }
            else
            {
                incLHalf(str, len, i_l);
                copyl2r(str, len, i_l);
                if(dCarry == 0)
                {
                    cout << str << endl;                
                }
                else
                {
                    cout << "1" << str << "1" << endl;                
                }
                return;
            }
        }
        else    //odd
        {
            int i_c = len / 2;
            int i_mis = findLgRInx(str, len, i_c + 1);
            if(i_mis != -1)
            {
                copyl2r(str, len, i_mis);
                cout << str << endl;            
            }
            else
            {
                int dmid = str[i_c] - '0';
                if(dmid < 9)
                {
                    str[i_c] = (dmid + 1) + '0';                
                }
                else
                {
                    str[i_c] = '0';
                    incLHalf(str, len, i_c - 1);
                    copyl2r(str, len, i_c);
                }
                if(dCarry == 0)            
                {
                    cout << str << endl;
                }
                else
                {
                    cout << "1" << str << "1" << endl;
                }
            }        
            return;
        }
    }
    
    int main() 
    {
        int cnt; cin >> cnt;    
        if(cnt == 0) return 0;
        
        //
        while(cnt --)
        {
            string str; cin >> str;            
            calc_next_palin((char*)str.c_str());        
        }
        return 0;
    } 
    View Code
  • 相关阅读:
    VS2010+C#写的3D的Android游戏开源咯....不来看别后悔哦。
    把XAML放在服务端,即改即现.....
    TagSL框架设计(1)先来点简介
    OpenMP模式下多线程文件操作 (转)
    VS获取工程版本信息
    OpenMP模式下多线程文件操作(五)
    简单建立DLL和使用DLL
    OpenMP模式下多线程文件操作(三)
    OpenMP模式下多线程文件操作(四)
    【转】VC2008在工具栏Toolbar里添加XP风格spin box control控件
  • 原文地址:https://www.cnblogs.com/tonix/p/3538549.html
Copyright © 2011-2022 走看看