Description
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个十进制数 56,将 56 加 65(即把 56 从右向左读),得到 121 是一个回文数。
又如:对于十进制数 8787:
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(100位之内),求最少经过几步可以得到回文数。如果在 30 步以内(包含 30 步)不可能得到回文数,则输出 Impossible!
。
Input
两行,分别是 N,M。
Output
如果能在 3030 步以内得到回文数,输出格式形如 STEP=ans
,其中 ans 为最少得到回文数的步数。
否则输出 Impossible!
。
Sample Input
10
87
Sample Output
STEP=4
Solution
没想到现在水平已经退化如此严重Orz,这题还做了很长时间= =
就是很简单的模拟就行 (但是好多代码写法都已经忘了还得回忆半天)
这个随笔就当做之后的简单模板好了qwq
Code
Ps:第一篇博客的话代码里就加上注释吧qwq
//By zuiyumeng
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define Re register
#define Fo(i,a,b) for(Re int i=(a),_=(b);i<=_;i++)
#define Ro(i,a,b) for(Re int i=(b),_=(a);i>=_;i--)//奇怪的自定义循环
using namespace std;
inline int read() {
int x=0,f=1; char c=getchar();
while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
return x*f;
}//顺手·快读
const int NUM=200;
int n,m,fig,ans;
int num1[NUM],num2[NUM],tmp[NUM];
char ch[NUM];
// void putout(int num[NUM]) {
// int Fig=0;
// while(num[++Fig]) cout<<num[Fig];
// cout<<endl;
// } 测试用输出
void solve() {
int Fig=0,t=0;
Ro(i,1,fig) {
int x=(num1[i]+num2[i]+t);
tmp[++Fig]=x%n; t=x/n;
}
if(t) tmp[++Fig]=t;
fig=Fig;
Fo(i,1,fig) num1[i]=tmp[fig-i+1];
} //核心:两数相加 其实就是用一个临时数组来储存求和结果再倒着赋给原来的num1
bool judge() {
Fo(i,1,fig/2) if(num1[i]!=num1[fig-i+1]) return 0;
return 1;
} //判断
int main() {
n=read();
scanf("%s",ch+1); fig=strlen(ch+1); //ch+1代表从1开始计(个人习惯)
Fo(i,1,fig) {
if(ch[i]>='0'&&ch[i]<='9') num1[i]=ch[i]-'0';
else num1[i]=ch[i]-'A'+10;
}
// putout(num1);
while(!judge()) {
ans++; if(ans>30) return printf("Impossible!"),0;
Fo(i,1,fig) num2[i]=num1[fig-i+1];
solve();
// putout(num1);
} //主循环模块
printf("STEP=%d",ans);
return 0;
}