算法训练 回文数
时间限制:1.0s 内存限制:256.0MB
问题描述
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个10进制数56,将56加65(即把56从右向左读),得到121是一个回文数。
又如:对于10进制数87:
STEP1:87+78 = 165 STEP2:165+561 = 726
STEP3:726+627 = 1353 STEP4:1353+3531 = 4884
在这里的一步是指进行了一次N进制的加法,上例最少用了4步得到回文数4884。
写一个程序,给定一个N(2<=N<=10或N=16)进制数M(其中16进制数字为0-9与A-F),求最少经过几步可以得到回文数。
如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible!”
输入格式
两行,N与M
输出格式
如果能在30步以内得到回文数,输出“STEP=xx”(不含引号),其中xx是步数;否则输出一行”Impossible!”(不含引号)
样例输入
9
87
样例输出
STEP=6
题意: 略,注意范围
分析: 主要是对进制的转化,细心点分析即可,这里可以不用stringsteam相关字符串流的,也是熟悉下吧,所以就这样写了,思路很清晰,就是模拟即可,麻烦了点,由于样例水了点,不然得高精度模拟,JAVA相对来说不怎么熟~~
参考函数
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
map<int,string> m;
void init(){
m[10] = 'A';m[11] = 'B';
m[12] = 'C';m[13] = 'D';m[14] = 'E';m[15] = 'F';
}
ll stringtoint(string s) {
stringstream ss(s);
ll res;
ss >> res;
return res;
}
string inttostring(ll x) {
ostringstream iss;
iss << x;
string res = iss.str();
return res;
}
bool check(string n) {
string s1,s2;
s1 = n;
s2 = s1;
reverse(s1.begin(),s1.end());
if(s1 == s2) return true;
return false;
}
ll f(int base,string n) {
ll res = 0;
ll a = 1;
while(true) {
string t = n.substr(n.size()-1,1);
int p;
if(base == 16 && t[0] >= 'A') {
p = t[0] - 'A' + 10;
} else {
p = t[0] - '0';
}
res += a*1ll*p;
n = n.substr(0,n.size()-1);
if(n.size() == 0) break;
a *= base;
}
return res;
}
string tobase(ll n,int base) {
string res = "";
while (n) {
int t = n % base;
char tt;
if(base == 16 && t > 9) {
tt = (char) ('A' + t - 10);
} else {
tt = (char) ('0' + t);
}
res = tt + res;
n /= base;
}
return res;
}
string get(string n,int base) {
ll res = 0;
res += f(base,n);
reverse(n.begin(),n.end());
res += f(base,n);
return tobase(res,base);
}
int main() {
init();
int base;
string n;
cin>>base>>n;
int res = 0;
while (res < 30) {
if(check(n)) {
break;
}
n = get(n,base);
res++;
}
if(res == 30) cout<<"Impossible!"<<endl;
else cout<<"STEP="<<res<<endl;
return 0;
}
- 如有错误或遗漏,请私聊下UP,ths
来源:CSDN
作者:nobleman__
链接:https://blog.csdn.net/nobleman__/article/details/78906176