六、余数是几
描述
已知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]展开看看相减是什么结果)