数论——同余

博客围绕数论展开,但具体内容较少,未呈现详细信息。数论是信息技术领域中数学相关的重要内容。

目录

一,同余

 CSU 1347 Last Digit

HDU 1061 Rightmost Digit

51Nod 1004 n^n的末位数字

CSU 1266 Divisible by 11

力扣 2598. 执行操作后的最大 MEX

二,高次同余式

三,2024年春晚魔术揭秘


一,同余

 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;
}

力扣 2598. 执行操作后的最大 MEX

给你一个下标从 0 开始的整数数组 nums 和一个整数 value 。

在一步操作中,你可以对 nums 中的任一元素加上或减去 value 。

  • 例如,如果 nums = [1,2,3] 且 value = 2 ,你可以选择 nums[0] 减去 value ,得到 nums = [-1,2,3] 。

数组的 MEX (minimum excluded) 是指其中数组中缺失的最小非负整数。

  • 例如,[-1,2,3] 的 MEX 是 0 ,而 [1,0,3] 的 MEX 是 2 。

返回在执行上述操作 任意次 后,nums 的最大 MEX 

示例 1:

输入:nums = [1,-10,7,13,6,8], value = 5
输出:4
解释:执行下述操作可以得到这一结果:
- nums[1] 加上 value 两次,nums = [1,0,7,13,6,8]
- nums[2] 减去 value 一次,nums = [1,0,2,13,6,8]
- nums[3] 减去 value 两次,nums = [1,0,2,3,6,8]
nums 的 MEX 是 4 。可以证明 4 是可以取到的最大 MEX 。

示例 2:

输入:nums = [1,-10,7,13,6,8], value = 7
输出:2
解释:执行下述操作可以得到这一结果:
- nums[2] 减去 value 一次,nums = [1,-10,0,13,6,8]
nums 的 MEX 是 2 。可以证明 2 是可以取到的最大 MEX 。

提示:

  • 1 <= nums.length, value <= 105
  • -109 <= nums[i] <= 109
class Solution {
public:
    int findSmallestInteger(vector<int>& nums, int k) {
        map<int,int>m;
        for(auto x:nums)m[(x%k+k)%k]++;
        int mins=INT_MAX,id=0;
        for(int i=0;i<k;i++){
            if(mins>m[i])mins=m[i],id=i;
        }
        return id+mins*k;
    }
};

二,高次同余式

(1)

 (2)

三,2024年春晚魔术揭秘

(1)数组初始化

初始化:[1,2,3,4,5,6,7,8]

其中1,5是一对,2,6是一对,3,7是一对,4,8是一对。

(2)任意旋转

把左边若干个数放到数组右边

新的数组和[x,x+1......x+7]mod 8同余

(3)把左边3个,插入右边5个的中间

理论上有4种情况:

x+3 x x+1 x+2 x+4 x+5 x+6 x+7

x+3 x+4  x x+1 x+2 x+5 x+6 x+7

x+3 x+4 x+5  x x+1 x+2 x+6 x+7

x+3 x+4 x+5 x+6 x x+1 x+2 x+7

(4)屁股底下

把第一个数放在屁股底下。

屁股底下一定是x+3,剩下的有4种情况:

x x+1 x+2 x+4 x+5 x+6 x+7

x+4  x x+1 x+2 x+5 x+6 x+7

x+4 x+5  x x+1 x+2 x+6 x+7

x+4 x+5 x+6 x x+1 x+2 x+7

(5)南方人 or 北方人?

把左边的1-3张插入到右边的4-6张中间

此时最多有12种情况,但最后一个一定是x+7

(6)男生 or 女生?

把左边的1-2张扔掉

此时最多有24种情况。

假设男生是a b c d e f,女生是a b c d e

男生的f和女生的e一定是x+7

(7)见证奇迹的时刻

把左边的1张放在最右边,重复7次

此时男生是b c d e f a,女生是c d e a b

(8)好运留下来,烦恼丢出去

男生是b c d e f a,女生是c d e a b

男生是d e f a b,女生是e a b c

男生是f a b d,女生是b c e

男生是b d f,女生是e b

男生是f b,女生是e

男生是f,女生是e

也就是说,剩下的一定是x+7

(9)魔法降临

屁股下面的x+3和剩下的x+7一定满足差值是4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值