这里所谓的“光棍”,并不是指单身汪啦~ 说的是全部由1组成的数字,比如1、11、111、1111等。传说任何一个光棍都能被一个不以5结尾的奇数整除。比如,111111就可以被13整除。 现在,你的程序要读入一个整数x,这个整数一定是奇数并且不以5结尾。然后,经过计算,输出两个数字:第一个数字s,表示x乘以s是一个光棍,第二个数字n是这个光棍的位数。这样的解当然不是唯一的,题目要求你输出最小的解。
提示:一个显然的办法是逐渐增加光棍的位数,直到可以整除x为止。但难点在于,s可能是个非常大的数 —— 比如,程序输入31,那么就输出3584229390681和15,因为31乘以3584229390681的结果是111111111111111,一共15个1。
输入格式:
输入在一行中给出一个不以5结尾的正奇数x(<1000)。
输出格式:
在一行中输出相应的最小的s和n,其间以1个空格分隔。
输入样例:
31
输出样例:
3584229390681 15
解题思路:
这道题的题目很容易理解,在难点上,题目也给了很明确的提示(题目已经说了s可能是个很大的数,这表示一定有一个测试点是一个位数相当大的,由于位数的原因,所以我们要用数组来保存这个位数很大的数,比如题目上的3584229390681)
代码实现:
#include<bits/stdc++.h>
using namespace std;
int main(){
string a="1";
int x,h;
vector<int> b;
cin>>x;
while(1){//进入死循环 ,第一次为1,第二次为11,之后每次位数加1,下面会有详解
vector<int>().swap(b);//这条语句的作用是将数组b清空 ,swap()函数是交换两个数组的值,
//这里是将数组b中的值与空数组交换了
h=0;//h为余数,第一次为0
int i;
for(i=0;i!=a.size();i++){//这个循环的作用是将光棍数除以x,并将结果保存在数组b中,
//之所以用数组是因为光棍数可能是一个很大的值,无法用一个变量保存
b.push_back(((int)a[i]-48+h*10)/x);//h为上一位的余数,第一次为0
h=((int)a[i]-48+h*10)%x;//求出本位的余数,
}
if(h==0){//经过for循环后,h仍未0的话,说明此次的while循环中的光棍数被x整除,则此次数组b中保存的值为题目要求的s
for(int j=0,flag=0;j!=b.size();j++){
if(b[j]!=0){//flag的作用是输出时不输出前导0,如数组b保存的数可能是00003584229390681(因为是用数组保存的数,所以存在前导0)
flag=1;
}
if(flag){
cout<<b[j];
}
}
cout<<" "<<a.size();//a.size()所得的是字符串a的长度,即题目中要求输入的n
return 0;//结束函数,此时输出的便是光棍数最小的情况
}else{//h不等于0,代表此次while循环的光棍数不能被x整除,
a+="1";//在原来的基础上乘10,再在个位数上+1,比如1变为11; 11变为111;
}
}
}