[luogu1015]回文数 (简单模拟+字符串)

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;
}
posted @ 2020-07-15 00:27  醉语梦  阅读(156)  评论(0编辑  收藏  举报