题意:有两个数n,m。有个冒号,冒号的左边是从0到n-1的七进制的数,右边是0到m-1的七进制的数。要求冒号左右不能有重复的数字,问总共有多少种情况。
思路:首先要求不能有重复的数字,就想到用一个数组来存每一个出现过的数字,数组初始化为0,出现过数字就++,这样也需要判断数字的位数,打表即可。最开始超时了,因为没有考虑数字长度问题,七进制,一共就0到6这七个数,所以只要数字大于117649,数字位数就按7去算就可以。还有一点,就是如果n和m的数字位数想加大于7就只需要考虑小于7的部分就可以了。具体看代码。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<string.h>
#include<string>
#include<map>
#include<vector>
#include<queue>
#define M(a,b) memset(a,b,sizeof(a))
#define ll long long
using namespace std;
ll length(ll a)//判断数字位数
{
if(a > 117649)
return 7;
if(a > 16807)
return 6;
if(a > 2401)
return 5;
if(a > 343)
return 4;
if(a > 49)
return 3;
if(a > 7)
return 2;
return 1;
}
ll judge(ll a, ll b, int la, int lb)//判断数字是否重复
{
int vis[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
while(la--)
{
if(vis[a%7])
return false;
vis[a%7]++;
a /= 7;
}
while(lb--)
{
if(vis[b%7])
return false;
vis[b%7]++;
b /= 7;
}
return true;
}
int main()
{
ll n, m;
while(~scanf("%lld%lld", &n, &m))
{
int len_n, len_m;//n和m的长度
len_n = length(n);
len_m = length(m);
ll sum = 0;
if((len_n+len_m) <= 7)
for(ll i = 0; i < n; i++)
{
for(ll j = 0; j < m; j++)
{
if(judge(i, j, len_n, len_m))
sum++;
}
}
printf("%d\n", sum);
}
return 0;
}