<题单>#4题解

题目链接:http://www.xujcoj.com/Home/Contest/cs/cid/766/ctype/1

1.可以整除的数字

题意:

给你一个正整数n,判断n能否被3、5、8、11中的一个或多个数整除。(n<1e50)

题解:

由于正整数过大,因此n用字符串进行存储,只要判断(n%3,5,8,11)是否等于0,也就是课上讲的大数取模,利用大数取模来进行判断即可。

大数取模:

一个数字abc%k
可以拆解为(((a*10)+b)*10+c)%k,根据乘法取模的性质,将取模运算符分配即可得到结果。

上板子

ll BigIntMod(string a, ll mod)
{
	ll sum = 0, n = a.length();
	for (int i = 0; i < n; i++)
	{
		sum = sum * 10 + a[i] - '0';
		sum %= mod;
	}
	return sum;
}

2.二进制取模

题意:

给你一个二进制数字,输出它在十进制下对1000000007取模的结果。

题解:

用字符串存这个数字,对于数字1010,可以分解为 ((((1*2)+0)*2+1)*2+0),同上题的大数取模思想,读者请触类旁通。

3.噬元兽的难题

题意:

输入三个18进制的数a,b,c,求其乘积

题解

将其转化成10进制进行乘法运算,再将其转换为18进制输出即可。

进制转换模板

// 把m进制的a转为10进制
ll convert_10(ll m, string a)
{
	ll sum = 0, n = a.length();
	for (int i = 0; i < n; i++)
	{
		if (a[i] >= '0' && a[i] <= '9')
			sum = sum * m + a[i] - '0';
		else
			sum = sum * m + a[i] - 'A' + 10;
	}
	return sum;
}

// 把十进制的num转成m进制
void convert_m(ll num, ll m)
{
	int a[100], x = 0;//a数组大小自行调整
	while (num)
	{
		a[x++] = num % m;
		num /= m;
	}
	for (int i = x - 1; i >= 0; i--)
	{
		if (a[i] >= 0 && a[i] <= 9)
			cout << a[i];
		else
			cout << char(a[i] - 10 + 'A');
	}
	cout << endl;
}

4.进制转换

板子题目

5.进制转换-2

题意:

给你一个二进制或十六进制的数字,请你完成他们之间的转换。

题解:

转化的规则:16进制转化成2进制每一位对应转化成2进制的4位,2进制转为16进制每四位转化成16进制的一位(不明白的话可以百度加深理解)。

上述规则理解了之后就可以进行代码的处理了,首先判断是2进制还是16进制,简单循环判断即可。

二进制
首先判断2进制的位数,如果不是4的倍速就在前面添加前导0

while (s.length() % 4 != 0)s = '0' + s;

对每4位进行2进制转10进制的处理,得到数字t。如果数字t<=9,直接输出,否则的话输出char(t-10+'A')。

十六进制
16进制转化成10进制,然后10进制转化成2进制。16进制转10进制:如果对应char<='9',对应的十进制t=char-'0',反之,t=ch-'A'+10

10进制转2进制直接套板子,转化成的二进制一定要4位,打个比方,比如11,要对其补前导0,变为0011。最后将我们的二进制依次存储到我们的ans字符串之中,最后要清除ans的前导0即可。

6.进制转换-3

题意:

输出数字在计算机中的存储形式,每8位用一个空格隔开,最后换行

题解:

位运算题,我们将二进制里每一位数存储到数组里,然后倒序输出即可。

		for (int i = 1; i <= 32; i++)
		{
			r[i] = (x & 1);
			x >>= 1;
		}

** 对(x&1)的解释**:一个数字的末尾如果是1,那么其数字&1为1,反之数字&1为0,我们不断对其进行&1运算,然后在右移执行32次,每次存到数组r里面,最后倒序输出即可。

7.数列乘积

题意:

题解:

这题的话,用大数字取模运算+慢速乘,唯一要注意的地方是,大数取模之中,(ans*10)这一块也要慢速乘,因为ans的取值范围和mod一样,而mod<=1e18,因此进行*10的操作会炸long long。

慢速乘板子:

ll mul(ll a, ll b,ll mod)
{
	ll ans = 0;
	while (b)
	{
		if (b & 1)
		{
			ans = ans + a;
			ans %= mod;
		}
		a = (a << 1) % mod;
		b >>= 1;
	}
	return ans;
}

8.高次幂运算-3

题意:

计算 a 的 b 次方对 1e9+7 取模以后的结果,(1 <= a,b <= 1e100)

题解:

大数字取模+快速幂运算
根据费马小定理

mod为素数时,\(a^b\%mod=a^{(b\%(mod-1))}\%mod\)

对于a我们也进行大数取模的化简,最后将结果用快速幂求得即可。

9.消失的零

题意:

一个数列,正整数,没有存在0的数字,现在求这个数列的第x项是多少。

题解:

实际上这题是9进制存储的变式,通常来说我们转化成其9进制即可。

唯一特别的地方就是,每一位的进制存储范围是从传统9进制的[0,8],变式为[1,9]的 。我们仔细观察,在我们对10进制的数字循环迭代的时候,0是如何出现的?,当我们数字x%9=0的时候,传统9进制对应的位数就是0,但是本题每一位范围的是[1,9],因当x%9=0的时候,我们将其化成(x-1)%9+1,就能改变其的取值范围了

		while (x)
		{
			int t = x % 9;
			if (t == 0)//被整除的时候 留一位
			{
				s.push((x - 1) % 9 + 1);
				x = (x - 1) / 9;
			}
			else//正常操作
			{
				s.push(x % 9);
				x = x / 9;
			}
		}	      
posted @ 2020-12-12 23:39  Fanxuwei  阅读(419)  评论(0编辑  收藏  举报