其他数论问题

目录

一,同余问题

CSU 1347 Last Digit

HDU 1061 Rightmost Digit

51Nod 1004 n^n的末位数字

CSU 1266 Divisible by 11

二,约数问题

POJ 1218 The Drunk Jailer

三,超级幂

HYSBZ 3884 上帝与集合的正确用法

四,最小公倍数问题

CSU 1704 LCM

五,其他数论问题

UVALive 2701 Find The Multiple

51Nod 2171 ProjectEuler 1 

力扣 1780. 判断一个数字是否可以表示成三的幂的和

力扣 1862. 向下取整数对和

力扣 2778. 特殊元素平方和

力扣 2815. 数组中的最大数对和

力扣 2862. 完全子集的最大元素和

面试题 17.09. 第 k 个数

力扣 479. 最大回文数乘积


一,同余问题

CSU 1347 Last Digit

题目:

Description
    The function f(n, k) is defined by f(n, k) = 1k + 2k + 3k +...+ nk. If you know the value of n and k, could you tell us the last digit of f(n, k)?
    For example, if n is 3 and k is 2, f(n, k) = f(3, 2) = 12 + 22 + 32 = 14. So the last digit of f(n, k) is 4.

Input
    The first line has an integer T (1 <= T <= 100), means there are T test cases.
    For each test case, there is only one line with two integers n, k (1 <= n, k <= 109), which have the same meaning as above.

Output
    For each test case, print the last digit of f(n, k) in one line.

Sample Input
10
1 1
8 4
2 5
3 2
5 2
8 3
2 4
7 999999997
999999998 2
1000000000 1000000000
Sample Output
1
2
3
4
5
6
7
8
9
0

思路:

按照mod2的余数和mod5的余数分开计算即可

代码:

#include<iostream>
using namespace std;
 
int main()
{
	int t, n, k;
	cin >> t;
	while (t--)
	{
		cin >> n >> k;
		int mod2 = 0, mod5 = 0;
		if (n % 4 == 1 || n % 4 == 2)mod2 = 1;
		if (k % 4)
		{
			k %= 4, n %= 5;
			for (int i = 1; i <= n; i++)
			{
				int r = 1;
				for (int j = 1; j <= k; j++)r *= i;
				mod5 += r;
			}
		}
		else mod5 = n - n / 5;
		mod5 %= 5;
		if (mod5 % 2 != mod2)mod5 += 5;
		cout << mod5 << endl;
	}
	return 0;
}

HDU 1061 Rightmost Digit

题目:

Description

Given a positive integer N, you should output the most right digit of N^N.  
Input

The input contains several test cases. The first line of the input is a single integer T which is the number of test cases. T test cases follow. 
Each test case contains a single positive integer N(1<=N<=1,000,000,000). 
 
Output

For each test case, you should output the rightmost digit of N^N. 
 
Sample Input

2
3

 
Sample Output

7

这个题目,无非就是把N分成10类。

不管N是多少,N^(k+4)和N^k都是模10同余的,利用这个就可以解决问题。

当然了,对有的N来说,周期不是4,是2或者1,差别不大。

我的代码:

#include<iostream>
using namespace std;
 
int main()
{
	int n,t;
	cin >> t;
	while (t--)
	{
		cin >> n;
		int nn = n % 10;
		if (nn == 0 || nn == 1 || nn == 5 || nn == 6 || nn == 9)cout << nn;
		else if (nn == 4)cout << 6;
		else
		{
			int m = n % 4;
			if (nn == 3 || nn == 7)
			{
				if (m == 1)cout << nn;
				else cout << 10 - nn;
			}
			else
			{
				if (m == 2)cout << 4;
				else cout << 6;
			}
		}
		cout << endl;
	}
	return 0;
}

51Nod 1004 n^n的末位数字

给出一个整数N,输出N^N(N的N次方)的十进制表示的末位数字。

Input

一个数N(1 <= N <= 10^9)

Output

输出N^N的末位数字

Sample Input

13

Sample Output

3

本题和HDOJ-1061 Rightmost Digit一样

#include<iostream>
using namespace std;

int main()
{
	int n;
    cin >> n;
    int nn = n % 10;
    if (nn == 0 || nn == 1 || nn == 5 || nn == 6 || nn == 9)cout << nn;
    else if (nn == 4)cout << 6;
    else
    {
        int m = n % 4;
        if (nn == 3 || nn == 7)
        {
            if (m == 1)cout << nn;
            else cout << 10 - nn;
        }
        else
        {
            if (m == 2)cout << 4;
            else cout << 6;
        }
    }
    cout << endl;
	return 0;
}

CSU 1266 Divisible by 11

题目:

Description
对于一个整数x,记x的自右向左的各位分别为第1位,第2位,……如果x奇数位上的数字之和减去偶数位上的数字之和所得的结果能被11整除,那么x就能被11整除。

Input
输入数据的第一行包含一个整数T (1 <= T <= 200),表示接下来一共有T组测试数据。

每组测试数据占一行,包含一个位数不超过100位的正整数x。

Output
对于每组测试数据,如果x能被11整除,输出“Yes”(不包括引号),否则输出“No”(不包括引号)。

Sample Input
3
111
1969
11111111111111111111
Sample Output
No
Yes
Yes

代码:

#include<iostream>
#include<string.h>
using namespace std;
 
int main()
{
	int T, s;
	char ch[101];
	cin >> T;	
	for (int i = 0; i < T; i++)
	{
		cin >> ch;
		s = 0;
		for (int i = 0; i < strlen(ch); i++)
			if (i % 2)s += ch[i] - '0';	else s -= ch[i] - '0';
		if (s % 11==0)cout << "Yes\n"; else cout << "No\n";
	}
	return 0;
}

二,约数问题

POJ 1218 The Drunk Jailer

题目:
Description

A certain prison contains a long hall of n cells, each right next to each other. Each cell has a prisoner in it, and each cell is locked. 
One night, the jailer gets bored and decides to play a game. For round 1 of the game, he takes a drink of whiskey,and then runs down the hall unlocking each cell. For round 2, he takes a drink of whiskey, and then runs down the hall locking every other cell (cells 2, 4, 6, ?). For round 3, he takes a drink of whiskey, and then runs down the hall. He visits every third cell (cells 3, 6, 9, ?). If the cell is locked, he unlocks it; if it is unlocked, he locks it. He repeats this for n rounds, takes a final drink, and passes out. 
Some number of prisoners, possibly zero, realizes that their cells are unlocked and the jailer is incapacitated. They immediately escape. 
Given the number of cells, determine how many prisoners escape jail.
Input

The first line of input contains a single positive integer. This is the number of lines that follow. Each of the following lines contains a single integer between 5 and 100, inclusive, which is the number of cells n. 
Output

For each line, you must print out the number of prisoners that escape when the prison has n cells. 
Sample Input

2
5
100
Sample Output

2
10

这个题目就是找规律。

每个门被改变的次数是它的编号有多少个约数。

所以说,这个题目就是要求,从1到n有多少个数有奇数个约数。

然而,当且仅当一个数是完全平方数的时候它有奇数个约数。

所以只要输出int(sqrt(n))即可

当然,n这么小,找到平方不超过n的最大数可以直接枚举。

代码:
 

#include<iostream>
using namespace std;
 
int main()
{
	ios_base::sync_with_stdio(false);
	int t, n;
	cin >> t;
	while (t--)
	{
		cin >> n;
		int i = 1;
		while (i*i <= n)i++;
		cout << i - 1 << endl;
	}
	return 0;
}

三,超级幂

HYSBZ 3884 上帝与集合的正确用法

题目:

根据一些书上的记载,上帝的一次失败的创世经历是这样的:
第一天,   上帝创造了一个世界的基本元素,称做“元”。
第二天,   上帝创造了一个新的元素,称作“α”。“α”被定义为“元”构成的集合。容易发现,一共有两种不同的“α”。
第三天,   上帝又创造了一个新的元素,称作“β”。“β”被定义为“α”构成的集合。容易发现,一共有四种不同的“β”。
第四天,   上帝创造了新的元素“γ”,“γ”被定义为“β”的集合。显然,一共会有16种不同的“γ”。
如果按照这样下去,上帝创造的第四种元素将会有65536种,第五种元素将会有2^65536种。这将会是一个天文数字。
然而,上帝并没有预料到元素种类数的增长是如此的迅速。他想要让世界的元素丰富起来,因此,日复一日,年复一年,他重复地创造着新的元素……
然而不久,当上帝创造出最后一种元素“θ”时,他发现这世界的元素实在是太多了,以致于世界的容量不足,无法承受。因此在这一天,上帝毁灭了世界。
至今,上帝仍记得那次失败的创世经历,现在他想问问你,他最后一次创造的元素“θ”一共有多少种?
上帝觉得这个数字可能过于巨大而无法表示出来,因此你只需要回答这个数对p取模后的值即可。
你可以认为上帝从“α”到“θ”一共创造了10^9次元素,或10^18次,或者干脆∞次。
一句话题意:

Input
接下来T行,每行一个正整数p,代表你需要取模的值
Output
T行,每行一个正整数,为答案对p取模后的值
Sample Input 3236
Sample Output 014Hint
对于100%的数据,T<=1000,p<=10^7

思路:

假设答案为f(p),p=2^s * pp,其中pp是奇数

那么根据欧拉公式可以递推式:f(p)=2^s*(2^(k)mod pp),其中k=f(phi(pp))-s,其中phi是欧拉函数

代码:
 

#include<iostream>
#include<stdio.h>
using namespace std;
 
int phi(int n)
{
	int r = n;
	for (int i = 2; i*i <= n; i++)
	{
		if (n%i == 0)
		{
			while (n%i == 0)n /= i;
			r = r / i*(i - 1);
		}
	}
	if (n > 1)r = r / n*(n - 1);
	return r;
}
 
long long mi(int n,int p)// 2^n % p
{
	if (n == 0)return 1 % p;
	long long r = mi(n / 2,p);
	r = r*r;
	if (n % 2)r *= 2;
	return r%p;
}
 
long long f(int n)
{
	if (n == 1)return 0;
	int s = 0, r = 1;
	while (n % 2 == 0)s++, n /= 2, r *= 2;
	int k = f(phi(n)) + phi(n) - s%phi(n);
	return mi(k, n)*r;
}
 
int main()
{
	int t, p;
	cin >> t;
	while (t--)
	{
		cin >> p;
		cout << f(p) << endl;
	}
	return 0;
}

四,最小公倍数问题

CSU 1704 LCM

题目:

Sample Input
4 10
Sample Output
2

题意:

给定正整数a,b,求正整数n使得a+n和b+n的最小公倍数最小

思路:

如果a=b那么n=1,否则的话不妨设a<b

设c=b-a,d=b+n

则问题转化成,给定正整数b,c,求d满足d>b使得(d-c)*d/gcd(c,d)最小,其中gcd是最大公约数函数

代码:

#include<iostream>
using namespace std;
 
int main()
{
	long long a, b, c, d;
	cin >> a >> b;
	if (a == b)
	{
		cout << 1;
		return 0;
	}
	if (a > b)a ^= b ^= a ^= b;
	c = b - a;
	if (b >= c * 2)
	{
		cout << c - b % c;
		return 0;
	}
	d = c * 2 - b;
	if (d*d < c)for (int i = b - c; i <= c; i++)if (c%i == 0)
	{
		cout << c + i - b;
		return 0;
	}
	for (int i = 1; c / i >= b - c; i++)if (c%i == 0)d = i;
	cout << c + c / d - b;
	return 0;
}

五,其他数论问题

UVALive 2701 Find The Multiple

题目:

Description

Given a positive integer n, write a program to find out a nonzero multiple m of n whose decimal representation contains only the digits 0 and 1. You may assume that n is not greater than 200 and there is a corresponding m containing no more than 100 decimal digits.
Input

The input file may contain multiple test cases. Each line contains a value of n (1 <= n <= 200). A line containing a zero terminates the input.
Output

For each value of n in the input print a line containing the corresponding value of m. The decimal representation of m must not contain more than 100 digits. If there are multiple solutions for a given value of n, any one of them is acceptable.
Sample Input

2
6
19
0
Sample Output

10
100100100100100100
111111111111111111
题目的大意就是找出n的倍数,而且是仅由0和1组成的十进制数,这就很有意思了。

因为不是比赛,只是训练,所以我花了一些时间做了一些推导。

首先写出来nextn函数

int nextn(int n)
{
	int m = n;
	if (n % 10 == 0)return n + 1;
	else
	{		
		int k = 1;
		while (n % 10)
		{
			m -= k;
			k *= 10;
			n /= 10;
		}
		m += k;
	}
	return m;
}

然后再写调用它的代码

int key = 1;
while (key%n)key = nextn(key);

这样对于一些n就可以得到答案了,甚至有可能是全部的n,这样就可以提交了,不过我没有试过。

接下来会用到我本就熟知的一些技巧。

第一,n里面2的次数不会超过7,5的次数就更不会了,所以代码可以变成

while (n % 2 == 0)n /= 2;
while (n % 5 == 0)n /= 5;
int key = 1;
while (key%n)key = nextn(key);
cout << "0000000" << endl;

也就是说,只需要考虑n不是2和5的倍数的情况即可。
第二,7*11*13=1001

第三,如果a整除b那么3a就整除bbb,9a就整除bbbbbbbbb(例如,如果b是101,那么bbb就是101101101)

这2个技巧又要怎么用呢?

主要就是根据这个来对n进行分类处理。
 

第一类,17整除n,那么n整除17*11*7*9,(n/17只能是1、11、7、9、3)

因为17*11*7整除100111011,这个是用nextn函数算出来的,我是边运行这个函数边半硬编码的,

所以n整除它写9遍,if (n % 17 == 0)for (int i = 0; i < 9; i++)cout << "100111011";

第二类,23整除n,那么n整除23*7*3(n/23只能是1、3、7)

因为23*7整除11101111,所以n整除它写3遍,if (n % 23 == 0)for (int i = 0; i < 3; i++)cout << "11101111";

第三类,27整除n,那么n只能是27、27*7、81

如果n是27或者27*7,因为21整除111111所以n整除111111写9遍,即54个1

如果是81,因为9整除111111111,所以n整除111111111写9遍,即81个1

if (n % 27 == 0)
{
    if (n == 81)for (int i = 0; i < 81; i++)cout << "1";
    else for (int i = 0; i < 54; i++)cout << "1";
}

第四类,n整除9* (7*11*13)^2   *19,之所以要这么分类是因为7*7*7超过了200而且19*19也超过了200

那么,7*11*13*19整除1000000001,所以(7*11*13)^2   *19整除1001000001001,

所以3*(7*11*13)^2   *19整除111111000111111,所以n整除这个数写3遍

else if (n % 9 == 0)for (int i = 0; i < 3; i++)cout << "111111000111111";

第五类,首先要明确,前面四类就是没有超过23的素因子的情况,那么第五类就是有一个不小于29的素因子的情况。

因为29*7超过了200,所以n只能是p或者3p的形式,p是从29到199的素数。

只要找到p的倍数,然后写3遍,它就是3p的倍数,也就是n的倍数了。

完整的代码:

#include<iostream>
using namespace std;
 
int nextn(int n)
{
	int m = n;
	if (n % 10 == 0)return n + 1;
	else
	{		
		int k = 1;
		while (n % 10)
		{
			m -= k;
			k *= 10;
			n /= 10;
		}
		m += k;
	}
	return m;
}
 
int main()
{
	int n;
	while (cin >> n)
	{
		if (n == 0)break;
		while (n % 2 == 0)n /= 2;
		while (n % 5 == 0)n /= 5;
		if (n % 17 == 0)for (int i = 0; i < 9; i++)cout << "100111011";
		else if (n % 23 == 0)for (int i = 0; i < 3; i++)cout << "11101111";
		else if (n % 27 == 0)
		{
			if (n == 81)for (int i = 0; i < 81; i++)cout << "1";
			else for (int i = 0; i < 54; i++)cout << "1";
		}
		else if (n % 9 == 0)for (int i = 0; i < 3; i++)cout << "111111000111111";
		else
		{
			if (n % 3 == 0)n /= 3;
			if (n % 19 == 0)n /= 19;
			if (1001 * 1001 % n == 0)for (int i = 0; i < 3; i++)cout << "111111000111111";
			else
			{
				int key = 1;
				while (key%n)key = nextn(key);
				for (int i = 0; i<3; i++)cout << key;
			}			
		}		
		cout << "0000000" << endl;
	}
	return 0;
}

果然效率很高,我是0ms,他们都是100-500ms

51Nod 2171 ProjectEuler 1 

如果我们列出所有小于10的3或5的倍数,我们可以得到3,5,6,9。
他们的和是23。

输入n,输出所有小于n,是3或5倍数的数之和。

Input

输入第一行组数T, 接下来T行,每行一个整数n。 (1 <= T <= 15) (0 <= n <= 1000)

Output

对于每组数据,输出一个数,表示所有小于n,是3或5倍数的数之和。

Sample Input

3
10
100
1000

Sample Output

23
2318
233168

思路:容斥原理

#include<iostream>
#include<algorithm>
using namespace std;

int f(int n,int a)
{
    return (1+n/a)*(n/a)/2*a;
}

int main()
{
    ios::sync_with_stdio(false);
    int t,n;
    cin>>t;
    while(t--){
        cin>>n;
        cout<<f(n-1,3)+f(n-1,5)-f(n-1,15)<<endl;
    }
    return 0;
}

力扣 1780. 判断一个数字是否可以表示成三的幂的和

给你一个整数 n ,如果你可以将 n 表示成若干个不同的三的幂之和,请你返回 true ,否则请返回 false 。

对于一个整数 y ,如果存在整数 x 满足 y == 3x ,我们称这个整数 y 是三的幂。

示例 1:

输入:n = 12
输出:true
解释:12 = 31 + 32

示例 2:

输入:n = 91
输出:true
解释:91 = 30 + 32 + 34

示例 3:

输入:n = 21
输出:false

提示:

  • 1 <= n <= 107
class Solution {
public:
    bool checkPowersOfThree(int n) {
        if(n%3==2)return false;
        if(n==0)return true;
        return checkPowersOfThree(n/3);
    }
};

力扣 1862. 向下取整数对和

给你一个整数数组 nums ,请你返回所有下标对 0 <= i, j < nums.length 的 floor(nums[i] / nums[j]) 结果之和。由于答案可能会很大,请你返回答案对109 + 7 取余 的结果。

函数 floor() 返回输入数字的整数部分。

示例 1:

输入:nums = [2,5,9]
输出:10
解释:
floor(2 / 5) = floor(2 / 9) = floor(5 / 9) = 0
floor(2 / 2) = floor(5 / 5) = floor(9 / 9) = 1
floor(5 / 2) = 2
floor(9 / 2) = 4
floor(9 / 5) = 1
我们计算每一个数对商向下取整的结果并求和得到 10 。

示例 2:

输入:nums = [7,7,7,7,7,7,7]
输出:49

提示:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 105
class Solution {
public:
	int sumOfFlooredPairs(vector<int>& nums) {
		vector<int>v(100001, 0),s(100001, 0);
		for (int x : nums)v[x]++;
		for (int i = 1; i < s.size(); i++)s[i] = s[i - 1]+v[i];
		long long ans = 0,p= 1000000007;
		for (int x = 1; x < v.size(); x++) {
			if (v[x] == 0)continue;
			int i = x + x - 1;
			for (; i < s.size(); i += x) {
				ans = (ans + i / x * (s[i] - s[i - x]) % p*v[x]) % p;
			}
			ans = (ans + i / x * (s[s.size() - 1] - s[i - x]) % p*v[x]) % p;
		}
		return ans;
	}
};

力扣 2778. 特殊元素平方和

给你一个下标从 1 开始、长度为 n 的整数数组 nums 。

对 nums 中的元素 nums[i] 而言,如果 n 能够被 i 整除,即 n % i == 0 ,则认为 num[i] 是一个 特殊元素 。

返回 nums 中所有 特殊元素 的 平方和 。

示例 1:

输入:nums = [1,2,3,4]
输出:21
解释:nums 中共有 3 个特殊元素:nums[1] ,因为 4 被 1 整除;nums[2] ,因为 4 被 2 整除;以及 nums[4] ,因为 4 被 4 整除。 
因此,nums 中所有元素的平方和等于 nums[1] * nums[1] + nums[2] * nums[2] + nums[4] * nums[4] = 1 * 1 + 2 * 2 + 4 * 4 = 21 。  

示例 2:

输入:nums = [2,7,1,19,18,3]
输出:63
解释:nums 中共有 4 个特殊元素:nums[1] ,因为 6 被 1 整除;nums[2] ,因为 6 被 2 整除;nums[3] ,因为 6 被 3 整除;以及 nums[6] ,因为 6 被 6 整除。 
因此,nums 中所有元素的平方和等于 nums[1] * nums[1] + nums[2] * nums[2] + nums[3] * nums[3] + nums[6] * nums[6] = 2 * 2 + 7 * 7 + 1 * 1 + 3 * 3 = 63 。 

提示:

  • 1 <= nums.length == n <= 50
  • 1 <= nums[i] <= 50
class Solution {
public:
    int sumOfSquares(vector<int>& nums) {
        int ans=0;
        for(int i=1;i<=nums.size();i++)if(nums.size()%i==0)ans+=nums[i-1]*nums[i-1];
        return ans;
    }
};

力扣 2815. 数组中的最大数对和

给你一个下标从 0 开始的整数数组 nums 。请你从 nums 中找出和 最大 的一对数,且这两个数数位上最大的数字相等。

返回最大和,如果不存在满足题意的数字对,返回 -1 。

示例 1:

输入:nums = [51,71,17,24,42]
输出:88
解释:
i = 1 和 j = 2 ,nums[i] 和 nums[j] 数位上最大的数字相等,且这一对的总和 71 + 17 = 88 。 
i = 3 和 j = 4 ,nums[i] 和 nums[j] 数位上最大的数字相等,且这一对的总和 24 + 42 = 66 。
可以证明不存在其他数对满足数位上最大的数字相等,所以答案是 88 。

示例 2:

输入:nums = [1,2,3,4]
输出:-1
解释:不存在数对满足数位上最大的数字相等。

提示:

  • 2 <= nums.length <= 100
  • 1 <= nums[i] <= 104
class Solution {
public:
    char maxNum(long long num, unsigned radix){
        char *s;
        int len=IntToStr(num,radix,s);
        char ans=0;
        for(int i=0;i<len;i++){
            ans=max(ans,s[i]);
        }
        return ans;
    }
    int maxSum(vector<int>& nums) {
        map<char,vector<int>>m;
        for(auto x:nums)m[maxNum(x,10)].push_back(x);
        int ans=-1;
        for(auto &mi:m){
            auto &v=mi.second;
            if(v.size()<2)continue;
            sort(v.begin(),v.end());
            ans=max(ans,v[v.size()-1]+v[v.size()-2]);
        }
        return ans;
    }
};

力扣 2862. 完全子集的最大元素和

给你一个下标从 1 开始、由 n 个整数组成的数组。

如果一组数字中每对元素的乘积都是一个完全平方数,则称这组数字是一个 完全集 。

下标集 {1, 2, ..., n} 的子集可以表示为 {i1, i2, ..., ik},我们定义对应该子集的 元素和 为 nums[i1] + nums[i2] + ... + nums[ik] 。

返回下标集 {1, 2, ..., n} 的 完全子集 所能取到的 最大元素和 。

完全平方数是指可以表示为一个整数和其自身相乘的数。

示例 1:

输入:nums = [8,7,3,5,7,2,4,9]
输出:16
解释:除了由单个下标组成的子集之外,还有两个下标集的完全子集:{1,4} 和 {2,8} 。
与下标 1 和 4 对应的元素和等于 nums[1] + nums[4] = 8 + 5 = 13 。
与下标 2 和 8 对应的元素和等于 nums[2] + nums[8] = 7 + 9 = 16 。
因此,下标集的完全子集可以取到的最大元素和为 16 。

示例 2:

输入:nums = [5,10,3,10,1,13,7,9,4]
输出:19
解释:除了由单个下标组成的子集之外,还有四个下标集的完全子集:{1,4}、{1,9}、{2,8}、{4,9} 和 {1,4,9} 。 
与下标 1 和 4 对应的元素和等于 nums[1] + nums[4] = 5 + 10 = 15 。 
与下标 1 和 9 对应的元素和等于 nums[1] + nums[9] = 5 + 4 = 9 。 
与下标 2 和 8 对应的元素和等于 nums[2] + nums[8] = 10 + 9 = 19 。
与下标 4 和 9 对应的元素和等于 nums[4] + nums[9] = 10 + 4 = 14 。 
与下标 1、4 和 9 对应的元素和等于 nums[1] + nums[4] + nums[9] = 5 + 10 + 4 = 19 。 
因此,下标集的完全子集可以取到的最大元素和为 19 。

提示:

  • 1 <= n == nums.length <= 104
  • 1 <= nums[i] <= 109
class Solution {
public:
    long long maximumSum(vector<int>& nums) {
        long long ans=0;
        for(int i=1;i<=nums.size();i++){
            long long s = 0;
            for(int j=1;j*j*i<=nums.size();j++)s+=nums[j*j*i-1];
            ans=max(ans,s);
        }
        return ans;
    }
};

面试题 17.09. 第 k 个数

有些数的素因子只有 3,5,7,请设计一个算法找出第 k 个数。注意,不是必须有这些素因子,而是必须不包含其他的素因子。例如,前几个数按顺序应该是 1,3,5,7,9,15,21。

示例 1:

输入: k = 5

输出: 9

思路:

这其实也是个组合问题,就是3个集合各选一个数的所有组合。

int main() {
	set<long long>s;
	for (long long x3 = 1; x3 <= INT_MAX; x3 *= 3) {
		for (long long x5 = 1; x5 <= INT_MAX; x5 *= 5) {
			long long m = x3 * x5;
			if (m > INT_MAX)break;
			for (long long x7 = 1; x7 <= INT_MAX; x7 *= 7) {
				if (m * x7 > INT_MAX)break;
				s.insert(m * x7);
			}
		}
	}
	for (auto x : s)cout << x << ",";
	return 0;
}

二次编码:

class Solution {
public:
    int getKthMagicNumber(int k) {
        vector<int>v{
            1,3,5,7,9,15,21,25,27,35,45,49,63,75,81,105,125,135,147,175,189,225,243,245,315,343,375,405,441,525,567,625,675,729,735,875,945,1029,1125,1215,1225,1323,1575,1701,1715,1875,2025,2187,2205,2401,2625,2835,3087,3125,3375,3645,3675,3969,4375,4725,5103,5145,5625,6075,6125,6561,6615,7203,7875,8505,8575,9261,9375,10125,10935,11025,11907,12005,13125,14175,15309,15435,15625,16807,16875,18225,18375,19683,19845,21609,21875,23625,25515,25725,27783,28125,30375,30625,32805,33075,35721,36015,39375,42525,42875,45927,46305,46875,50421,50625,54675,55125,59049,59535,60025,64827,65625,70875,76545,77175,78125,83349,84035,84375,91125,91875,98415,99225,107163,108045,109375,117649,118125,127575,128625,137781,138915,140625,151263,151875,
153125,164025,165375,177147,178605,180075,194481,196875,212625,214375,229635,231525,234375,250047,252105,253125,273375,275625,295245,297675,300125,321489,324135,328125,352947,354375,382725,385875,390625,413343,416745,420175,421875,453789,455625,459375,492075,496125,531441,535815,540225,546875,583443,588245,590625,637875,643125,688905,694575,703125,750141,756315,759375,765625,820125,823543,826875,885735,893025,900375,964467,972405,984375,1058841,1063125,1071875,1148175,1157625,1171875,1240029,1250235,1260525,1265625,1361367,1366875,1378125,1476225,1488375,1500625,1594323,1607445,1620675,
1640625,1750329,1764735,1771875,1913625,1929375,1953125,2066715,2083725,2100875,2109375,2250423,2268945,2278125,2296875,2460375,2470629,2480625,2657205,2679075,2701125,2734375,2893401,2917215,2941225,2953125,3176523,3189375,3215625,3444525,3472875,3515625,3720087,3750705,3781575,3796875,3828125,4084101,4100625,4117715,4134375,4428675,4465125,4501875,4782969,4822335,4862025,4921875,5250987,5294205,5315625,5359375,5740875,5764801,5788125,5859375,6200145,6251175,6302625,6328125,6751269,6806835,6834375,6890625,7381125,7411887,7441875,7503125,7971615,8037225,8103375,8203125,8680203,8751645,8823675,
8859375,9529569,9568125,9646875,9765625,10333575,10418625,10504375,10546875,11160261,11252115,11344725,11390625,11484375,12252303,12301875,12353145,12403125,13286025,13395375,13505625,13671875,14348907,14467005,14586075,14706125,14765625,15752961,15882615,15946875,16078125,17222625,17294403,17364375,17578125,18600435,18753525,18907875,18984375,19140625,20253807,20420505,20503125,20588575,20671875,22143375,22235661,22325625,22509375,23914845,24111675,24310125,24609375,26040609,26254935,26471025,26578125,26796875,28588707,28704375,28824005,28940625,29296875,31000725,31255875,31513125,31640625,
33480783,33756345,34034175,34171875,34453125,36756909,36905625,37059435,37209375,37515625,39858075,40186125,40353607,40516875,41015625,43046721,43401015,43758225,44118375,44296875,47258883,47647845,47840625,48234375,48828125,51667875,51883209,52093125,52521875,52734375,55801305,56260575,56723625,56953125,57421875,60761421,61261515,61509375,61765725,62015625,66430125,66706983,66976875,67528125,68359375,71744535,72335025,72930375,73530625,73828125,78121827,78764805,79413075,79734375,80390625,85766121,86113125,86472015,86821875,87890625,93002175,93767625,94539375,94921875,95703125,
100442349,101269035,102102525,102515625,102942875,103359375,110270727,110716875,111178305,111628125,112546875,119574225,120558375,121060821,121550625,123046875,129140163,130203045,131274675,132355125,132890625,133984375,141776649,142943535,143521875,144120025,144703125,146484375,155003625,155649627,156279375,157565625,158203125,167403915,168781725,170170875,170859375,172265625,182284263,183784545,184528125,185297175,186046875,187578125,199290375,200120949,200930625,201768035,202584375,205078125,215233605,217005075,218791125,220591875,221484375,234365481,236294415,238239225,239203125,241171875,244140625,257298363,258339375,259416045,260465625,262609375,263671875,279006525,281302875,282475249,283618125,284765625,287109375,301327047,
303807105,306307575,307546875,308828625,310078125,330812181,332150625,333534915,334884375,337640625,341796875,358722675,361675125,363182463,364651875,367653125,369140625,387420489,390609135,393824025,397065375,398671875,401953125,425329947,428830605,430565625,432360075,434109375,439453125,465010875,466948881,468838125,472696875,474609375,478515625,502211745,506345175,510512625,512578125,514714375,516796875,546852789,551353635,553584375,555891525,558140625,562734375,597871125,600362847,602791875,605304105,607753125,615234375,645700815,651015225,656373375,661775625,664453125,669921875,703096443,
708883245,714717675,717609375,720600125,723515625,732421875,771895089,775018125,778248135,781396875,787828125,791015625,837019575,843908625,847425747,850854375,854296875,861328125,903981141,911421315,918922725,922640625,926485875,930234375,937890625,992436543,996451875,1000604745,1004653125,1008840175,1012921875,1025390625,1076168025,1085025375,1089547389,1093955625,1102959375,1107421875,1162261467,1171827405,1181472075,1191196125,1196015625,1205859375,1220703125,1275989841,1286491815,1291696875,1297080225,1302328125,1313046875,1318359375,1395032625,1400846643,1406514375,1412376245,1418090625,
1423828125,1435546875,1506635235,1519035525,1531537875,1537734375,1544143125,1550390625,1640558367,1654060905,1660753125,1667674575,1674421875,1688203125,1708984375,1793613375,1801088541,1808375625,1815912315,1823259375,1838265625,1845703125,1937102445,1953045675,1969120125,1977326743,1985326875,1993359375,2009765625,2109289329,2126649735,2144153025
        };
        return v[k-1];
    }
};

力扣 479. 最大回文数乘积

给定一个整数 n ,返回 可表示为两个 n 位整数乘积的 最大回文整数 。因为答案可能非常大,所以返回它对 1337 取余 。

示例 1:

输入:n = 2
输出:987
解释:99 x 91 = 9009, 9009 % 1337 = 987

示例 2:

输入: n = 1
输出: 9

提示:

  • 1 <= n <= 8

思路:

这题用数论的方法去求,应该能有一些结果,不过还是二次编码更香。


long long intRev(int x) {
	stack<int>v;
	while (x)v.push(x % 10), x /= 10;
	int ans = 0, mi = 1;
	while (!v.empty())ans += v.top()*mi, mi *= 10, v.pop();
	return ans;
}
bool check(long long x,int mi)
{
	int a = mi;
	while (a >= mi / 10) {
		if (x / a >= mi)break;
		if (x%a == 0) {
			return true;
		}
		a--;
	}
	return false;
}
int main()
{
	for (int i = 1; i <= 8; i++) {
		int mi = 1, j = i;
		while (j--)mi *= 10;
		long long x = mi - 1;
		while (true) {
			long long y = x * mi + intRev(x);
			if (check(y, mi)) {
				cout << y%1337 <<",";
				break;
			}
			x--;
		}		
	}
	return 0;
}

输出:

0,987,123,597,677,1218,877,475,

如果不要%1337则输出0,9009,906609,99000099,9966006699,999000000999,99956644665999,9999000000009999,

所以,只有n=1时满足条件的最大回文数是9,2<=n<=8时满足条件的最大回文数都是偶数位。

二次编码:

class Solution {
public:
    int largestPalindrome(int n) {
        vector<int>v{9,987,123,597,677,1218,877,475};
        return v[n-1];
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值