2021级c++上机模拟考小结(下)

六、余数是几

描述

已知a和b两个正整数互质(即最大公因数为1),且b是质数,求a的b-1次方除以b的余数

输入

多组案例。一个正整数n,表示案例的数量。(n<=1000)

每组案例由两个正整数a和b组成。(均不大于1e+8)

输出

针对每组案例,输出一个整数,表示a的b-1次方除以b的余数

样例输入

1
3 5
 

样例输出

1

关键代码

*****
ll quickPower(ll a, ll b)//快速幂
{
	ll ans = 1;
	while (b)
	{
		if (b & 1)
			ans = ans * a % mod;
		a = a * a % mod;
		b >>= 1;
	}
	return ans;
}
*****
int ans = 0;
mod = b;
ans = quickPower(a, b - 1);
cout << ans << endl;
*****
//数学大佬的方法
cout<<1<<endl;
*****

解释

首先是熟读并背诵的快速幂运算,因为乘方次数很大用pow会超时,数据也远远超long long的范围,然后根据题目要求运用快速幂运算就好了。但是此题是有一个定理叫费马小定理,查找百度百科可知:费马小定理(Fermat's little theorem)是数论中的一个重要定理,在1636年提出。如果p是一个质数,而整数a不是p的倍数,则有a^(p-1)≡1(mod p)。所以这道题只要输入符合要求的数字,最后的答案都是1。

七、数列-8

描述

已知一个数列的第1项为1,第2项为2,从第三项开始起,通项公式是an=2*an-1+an-2,求数列第m项的千位数。

输入

多组案例。一个正整数n,表示案例的数量。(n<=100)

每组案例由一个正整数m组成。(m<=10000)

输出

针对每组案例,输出一个整数,表示数列第m项的千位数。

每组案例输出完要换行。

样例输入

2
3
10
 

样例输出

0

2

关键代码

*****
int a[10014] = { 0,1,2 };
for (int i = 3; i <= 10000; i++)
{
	a[i] = 2 * a[i - 1] + a[i - 2];
	a[i] %= 10000;
}
*****
int ans = a[m] / 1000 % 10;
*****

解释

上半代码是一个预处理,因为题目显示m<10000,所以可以把10000个数字都先算出来,然后再进行查询(主要是怕超时,后来发现好像输入一个m,再算也不会超时)。由于到后面的数字越来越大,甚至超过long long 的范围,所以在预处理的时候将他的万位以上的数字都给舍去,因为能影响千位的只有千位以下的。所以对10000取模就行了。

八、吃豆人

描述

吃豆人(Pac-Man)是Namco公司1980年在街机上发布的一款游戏。游戏中玩家控制吃豆人吃豆子,并且避开追杀玩家的怪物。如果玩家吃到了能量豆,则可以处于无敌状态,反杀怪物。

已知每吃一个能量豆,就可以维持m秒的无敌时间。如果在无敌时间还没结束前,又吃了个能量豆,则会进入一段新的m秒无敌时间,也就是相当于原有的无敌立即结束,随即开启m秒的无敌时间。

吃豆人在游戏过程中一共吃下了a个能量豆,每个能量豆分别是第t1、t2、...、ta秒吃下,问吃豆人总共维持多少秒无敌。

输入

多组案例。一个正整数n,表示案例的数量。(n<=20)

每组案例先是两个正整数m和a,表示单个能量豆无敌的时间、吃下能量豆的数量,(m<=1000, a<=1000)

然后是a个非负整数t1、t2、...、ta,表示每个能量豆吃下的时间点。(均不大于1e+6)

输出

针对每组案例,输出一个整数,表示总共无敌的时间。

每组案例输出完要换行。

样例输入

1
2 3
1 4 5
 

样例输出

5

关键代码

*****
sort(x, x + a);
*****
for (int i = 1; i < a; i++)
{
	if (x[i] - x[i - 1] >= m)
		ans += m;
	else
		ans = ans + x[i] - x[i - 1];
}
*****

解释

本来是想边读入边判断的(因为怕超时),然后吃了很多个wa,因为输入的时间点不是按顺序的,所以用数组将时间存起来,然后进行排序,接着就是判断无敌时间,如果前后两个的间隔小于无敌时间,那么无敌时间只有这两个时间点的间隔那么长,如果前后两个的间隔大于无敌时间,那么无敌时间就是无敌时间,最后一个时间点的无敌时间一定是满的。

九、字典序排序

描述

把m个单词按照字典序排序,假设这些单词都只由大小写字母组成,并且注意字典序是无视大小写,并且A/a在最前,Z/z在最后。例如在字典序中,字符串"CPP"比"code"大,"ABC"和"aBc"是相等的。

输入

多组案例。一个正整数n,表示案例的数量。(n<=20)

每组案例先是一个正整数m,表示字符串的个数,(m<=30)

然后是m个字符串。(字符串长度不大于100)

输出

针对每组案例,输出m个字符串,是把原有m个字符串按字典序从小到大排序后的结果;如果有两个字符串字典序相等,则按照字符串的值从小到大排。

每两个字符串之间要有一个空格。

每组案例输出完要换行。

样例输入

1
5
CPP code ABC aBc BBB
 

样例输出

ABC aBc BBB code CPP

关键代码

*****
string strTolower(string a)
{
	for (int i = 0; i < a.size(); i++)
	{
		a[i] = tolower(a[i]);
	}
	return a;
}
bool cmp(string a, string b)
{
	string a1 = strTolower(a), b1 = strTolower(b);
	return a1 < b1 || a1 == b1 && a < b;
}
*****
sort(a, a + m, cmp);
*****

解释

这道题用sort的第三个参数就很简单(因为这道题,特意去学了一下,考试的排序题就很简单啦)。第一个函数是将字符串所有的字符都转成小写字母,第二个函数 cmp,也就是sort的第三个参数,我把他想成是定义一个排序规则(前提是必须是bool类型),所以按照题意按字典序从小到大排序后的结果,如果有两个字符串字典序相等,则按照字符串的值从小到大排。写一个cmp再在主函数调用一下sort就行啦。

十、质因数之和的和

描述

令f(x)表示一个正整数x的所有质因数的和。

有m个正整数保存在长度为m的数组a中,给定两个合法下标c和d,输出下标范围内所有数组元素x的f(x)值的总和,即f(a[c])+f(a[c+1])+...+f(a[d])。

输入

单组案例。

一个正整数m,表示数组元素的个数,(m<=100000)

然后是m个正整数,表示数组每个元素的值,(均不大于1e+7)

接下来是一个正整数q,表示有q次查询,(q<=100000)

每次查询占一行,由两个非负整数c和d组成,表示需要参与计算的元素的下标范围从c到d。(0<=c<=d<=m-1)

输出

针对每次查询,输出一个长整数,表示f(a[c])+f(a[c+1])+...+f(a[d])的值。

每次查询结果输出完要换行。

样例输入

5
2 6 7 9 3
2
0 2
1 4
 

样例输出

14

18

关键代码

*****
for (int i = 0; i < m; i++)
{
	cin >> num[i];
	for (int j = 2; j <= sqrt(num[i]); j++)
	{
		if (num[i] % j == 0)
		{
			a[i + 1] += j;
			while (num[i] % j == 0)
				num[i] /= j;
		}
	}
	if (num[i] > 1)
		a[i + 1] += num[i];
	a[i + 1] += a[i];
}
*****
ll ans = a[d + 1] - a[c];

解释

这道题有两个预处理首先是寻找100000以内所有数的质因数的和,用唯一分解定理,然后是前缀和,就是代码中的a[i+1]+=a[i],这样就能实现现在的a[i]就是以前的a[1]+a[2]+a[3]+……+a[i];的效果,然后寻找一个区间内的和只要算a[d+1]-a[c]就是答案啦(如果没懂的话可以拿出纸笔将a[d+1],a[d],a[c]展开看看相减是什么结果)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值