P1015 [NOIP1999 普及组] 回文数

  • 写在前面

    1. 由于某些原因导致了这道题四个测试点居然WA了两次太羞耻了:(

    2. 记得考虑输入格式:十六进制的输入得用char读

  • 分析

    1. 先看输入输出格式:输入两行,输出一行
    2. 再看输入意义:N为进制数,M为输入数据
    3. 再看输出意义:
      1. 能得到:printf("STEP=%d",ans);
      2. 得不到:printf("Impossible!");(有个叹号!!!)
    4. 再看题面:
      1. 回文数:长度为\(l\)时,第\(i\)个数等于第(\(l-i-1\))个数
      2. 数M的长度在100位之内:高精度
      3. 30步以内能否得到回文数:不断计算直至第30次,如果出现回文数就跳出循环,否则继续
      4. 我也不知道写点啥好了但是不写这行好像太少了
    5. 由题面可知,这道题至少需要高精度、一个用于检查回文数的函数
  • 开码

    1. 读入(注意十六进制)

      int h2i(char s){
      	if(s>='0'&&s<='9') return s-'0';
      	if(s>='A'&&s<='F') return s-'A'+10;
      }
      void input(){
      	char M[105];
      	scanf("%d%s",&N,&M);
      	l = strlen(M);
      	for(int i = l-1;i>=0;i--){
      		A[i] = h2i(M[l-i-1]);
      	}
      }
      

      注意:读入的16进制数不能直接用int数组存;读入时倒序比后期倒序会好写些(就是懒罢了)

    2. 检查是否为回文数

      bool check(){
      	for(int i = 0;i<l;i++){
      		if(A[i]!=A[l-i-1]) return false;
      	}
      	return true;
      }
      

      注意其实没啥好主意的我只是想保持格式整齐

    3. 回文数高精度加法

      void p(){
      	for(int i = 0;i<l;i++){
      		res[i] = A[i] + A[l-i-1];
      	}//直接进行一个回文数的加而不用另开数组存储其回文数
      	for(int i = 0;i<l;i++){
              
      		int nex = i+1;//下一个下标号,用于进位以及判断是否超出原来位数
              
      		if(res[i] >= N){
      			if(nex >= l) l++;//若超出原来位数则位数+1
                  
      			res[nex] += (res[i]/N);
      			res[i] %= N;
                  //进行一个位的进(bushi
      		}
      	}
      	for(int i = 0;i<l;i++){
      		A[i] = res[i];
      	}//将结果数组中的值赋值回A(由于是正数加法所以没必要将A数组清空,直接覆盖就行)
      }
      

      注意:注释

    4. 主函数

      int main() {
          //因为是全局数组所以就不用初始化了,初始全部为0
      	input();
      	for(int i = 0; i<30; i++) {
      		if(check()) {
      			printf("STEP=%d",i);
      			return 0;
      		}
      		p();
      	}
      	printf("Impossible!");//叹号!!!!!!啊啊啊啊啊啊啊啊
      	return 0;
      }
      

      注意:注意审题,实在不行复制也可以

posted @ 2021-11-24 14:03  Burnling  阅读(252)  评论(0编辑  收藏  举报