洛谷P1015 [NOIP1999 普及組] 回文數(C++)【回文數,高精度,進制轉換】詳細解析+代碼注釋


洛谷P1015 [NOIP1999 普及組] 回文數

題目鏈接

題目描述

若一個數(首位不為零)從左向右讀與從右向左讀都一樣,我們就將其稱之為回文數。

例如:給定一個十進制數 56,將 56 加 65(即把 56 從右向左讀),得到 121 是一個回文數。

又如:對於十進制數 87:

STEP1:87+78=165
STEP2:165+561=726
STEP3:726+627=1353
STEP4:1353+3531=4884

在這里的一步是指進行了一次 N 進制的加法,上例最少用了 4 步得到回文數 4884。

寫一個程序,給定一個 N(\(2 \leq N \leq 10\) 或 N=16)進制數 M(100 位之內),求最少經過幾步可以得到回文數。如果在 30 步以內(包含 30 步)不可能得到回文數,則輸出 Impossible!

輸入格式

兩行,分別是 N ,M。

輸出格式

如果能在 30 步以內得到回文數,輸出格式形如 STEP=ans,其中 ans 為最少得到回文數的步數。

否則輸出 Impossible!

輸入輸出樣例

輸入 #1

10
87

輸出 #1

STEP=4

題目分析

回文數不用多說,反轉后判等。需要注意的有兩點,一是本題允許多種進制,二是M的范圍可以達到100位,顯然要用到高精度了。

解題思路

首先利用字符串接收數字。對字符串進行遍歷將其每一位轉換為整型數進行存儲,這里需要注意的是16進制要區分字母大小寫。利用reverse函數實現反轉操作。執行相加操作前,首先要判斷第一次輸入的原數是不是回文數,如果是那么ans為0,程序結束。執行高精度加法時,具體進位邏輯見代碼,需注意的是我們執行的是一個數和它的倒序相加,所以向前或向后進位對本題無影響。

代碼

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>

using namespace std;

int n,ans;
string str;
vector<int> s1,s2;

int main()
{
	cin>>n;
	cin>>str;
	for(int i=0;i<str.length();i++)		//將字符串表示的數字每一位轉換為整形進行存儲 
	{
		if(str[i]>='0'&&str[i]<='9')
			s1.push_back(str[i]-'0');
		else
			if(str[i]>='A')				//十六進制需注意字母大小寫 
				s1.push_back(str[i]-'A'+10);
			else
				s1.push_back(str[i]-'a'+10);
	}
	s2=s1;
	reverse(s1.begin(),s1.end());		//反轉函數 
	if(s1==s2)
	{
		cout<<"STEP=0";
		return 0;
	}
	while(++ans<=30)	//計數 
	{
		int len=s1.size();
		for(int i=0;i<len;i++)	//高精度加法 
		{
			s1[i]+=s2[i];	//對應位相加 
			if(s1[i]>=n)	//某一位大於n時需進行進位操作 
			{
				if(i!=len-1) s1[i+1]++;	//每次最多進1,這里由於兩數互相倒序,向前進位與向后進位對本題無影響 
				else s1.push_back(1);	//當最后一位滿n,進位需要多申請一個位置進位
			}
			s1[i]%=n;	//進位后留下余數 
		}
		s2=s1;
		reverse(s1.begin(),s1.end());
		if(s1==s2)
		{
			cout<<"STEP="<<ans;
			return 0;
		}
	}
	cout<<"Impossible!";
	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM