题意:给你一个N进制的数R,求能表示R的最小进制N,并且满足R能被N-1整除。进制范围[2,62]。输入的时候可能会出现0-9,A-Z,a-z字符。
分析:
1.R%(N-1) == 0
对于n进制的数abcd,sum = a*n3+b*n2+c*n+d,sum%(n-1) ==0,也就是 (a*n3+b*n2+c*n+d)%(n-1) == 0
nt%(n-1) = (1+n-1)t % (n-1) = 1,因此对于sum%(n-1) == 0 --> 只需要满足a+b+c+d ==0即可,这是关键的判断条件。
2.能表示数R
这需要进制X(能取到[0,X))满足:X-1 >= R的所有位中最大的那个数。
然后求满足这两个条件的最小X即可。
代码一:字符数组存储
/*
@Filename: code.cpp
@Version: 1.0
@Author: wyl6
@Email: 17744454343@163.com
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <stack>
#include <queue>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <bitset>
#include <list>
#include <sstream>
#include <set>
#include <map>
#include <functional>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 1000
typedef long long ll;
char s[35000];
ll sum;
int maxx;
bool flag;
int deal(char a)
{
if (a >= '0' && a<= '9') return a-'0';
if (a >= 'A' && a <= 'Z') return a-'A'+10;
if (a >= 'a' && a <= 'z') return a-'a'+36;
}
int main()
{
while(scanf("%s",&s) != EOF)
{
sum = 0;
maxx = 0;
flag = false;
for (int i = 0; s[i] != '\0'; ++i) {//也可以先求出strlen(s),再代入循环
int dealans = deal(s[i]);
sum += dealans;
maxx = max(maxx,dealans); }
for (int i = maxx; i <= 61; ++i) {
if (sum%i == 0) {
printf("%d\n",i+1);
flag = true;
break;
}
}
if(!flag) printf("such number is impossible!\n");
}
return 0;
}
代码二:string存储
/*
@Filename: code.cpp
@Version: 1.0
@Author: wyl6
@Email: 17744454343@163.com
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <stack>
#include <queue>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <bitset>
#include <list>
#include <sstream>
#include <set>
#include <map>
#include <functional>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 1000
typedef long long ll;
string s;
ll sum;
int maxx;
bool flag;
int deal(char a)
{
if (a >= '0' && a<= '9') return a-'0';
if (a >= 'A' && a <= 'Z') return a-'A'+10;
if (a >= 'a' && a <= 'z') return a-'a'+36;
}
int main()
{
while(cin >> s){
sum = 0;
maxx = 0;
flag = false;
for (int i = 0; i < s.size(); ++i) {
int dealans = deal(s[i]);
sum += dealans;
maxx = max(maxx,dealans);
}
for (int i = maxx; i <= 61; ++i){
if (sum%i == 0) {
printf("%d\n",i+1);
flag = true;
break;
}
}
if(!flag) printf("such number is impossible!\n");
}
return 0;
}
===================================================================================================================================
p.s.
这次被strlen坑到了,strlen本身复杂度O(n),用strlen计算的话,超时了:
for (int i = 0; i < strlen(s); ++i) {
int dealans = deal(s[i]);
sum += dealans;
maxx = max(maxx,dealans);
}
s可取到32KB,测试发现char空间是1B,所以strlen(s)可取到32*1024,循环次数32*1024,只看for内的复杂度就是32*32*1024*1024,大约是10的9次方。
不超时才怪!!!