题目:https://gesp.ccf.org.cn/101/attach/1684804529553440.pdf

选择题:

1.答案:A

解析:链表需要循序访问,不能随机访问任何一个元素。

2.答案:A

解析:一眼就不对,p->next->prev原来指向p,现在指向p->next,就是自己。P->prev->next原来指向p,现在指向p->prev,也是自己。所以链断了。

3.答案:B

解析:A,head的前驱不需要赋值;C,tail的后驱不需要赋值;D,tail没有连上head

4.答案:B

解析:代入即可

5.答案:D

解析:唯一分解定理,每一项都是质因数

6.答案:C

解析:把当前所有小于n的i的倍数都设为不是质数

7.答案:A

解析:递归时函数的参数和结果保存在“栈”中。

8.答案:D

解析:factorialB不是递归

9.答案:A

解析:选择排序在交换时,可能会把后面的相等元素移动到前面,破坏原始顺序

10.答案:B

解析:1.由于i=low-1,所以要先i++;2.由于基准是每段的末尾,所以先要把小于基准的数堆到当前分段的前部。

11.答案:C

解析:⌈log2​100⌉=7,向上取整

12.答案:A

解析:避免整数溢出:(left + right) 在 left 和 right 很大时可能溢出,但 left + (right - left) / 2 不会。等价于 (left + right) / 2,但更安全。

13.答案:A

解析:贪心的核心是先选择,选择当前最优解,但贪心不是一定能找到最优解。

14.答案:D

解析:首先排除A,然后排除C,return 0不可能获得最大值,且还return leftMax*rightMax,就更不符合逻辑。最后排除B,return leftMax+rightMax不符合逻辑。

15.答案:B

解析:carry是上一位的进位值,所以选B

判断题:

1.答案:T

解析:注意,这里是将p的“值”设为p->next的值,不是将p=p->next。是p.val=p->next->val。

2.答案:F

解析:链表中的存储单元是动态分配的,不需要连续。

3.答案:T

解析:如题所述。

4.答案:F

解析:贪心做的的最有选择,不一定是最优解。      

5.答案:T

解析:如题所述。

6.答案:F

解析:快排平均复杂度为为O(nlogn),最差为O(n2)

7.答案:T

解析:如题所述。

8.答案:F

解析:只适用于有序数组

9.答案:F

解析:贪心

10.答案:T

解析:如题所述。

编程题:


思路

首先,我们假设所有物品全部卖给小 B,则收入为 ∑i=12n​bi​。

而第 i 件物品从卖给小 B 变成卖给小 C 对收入的贡献为 ci​−bi​。

所以我们只需对 ci​−bi​ 进行排序,选出前 n 个最大的,求和并加上全部卖给小 B 的收入即可。

代码

#include<bits/stdc++.h>
using namespace std;
long long n,b[200005],c,a[200005],ans;
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n;
    for(int i=0;i<n*2;i++) cin>>b[i],ans+=b[i];  //全部卖给小 B 的收入
    for(int i=0;i<n*2;i++) cin>>c,a[i]=c-b[i];   //记录第 i 件物品对答案的贡献
	sort(a,a+n*2,greater<long long>());          //从大到小排序
	for(int i=0;i<n;i++) ans+=a[i];              //更新答案
	cout<<ans;
    return 0; 
}

题意:

对于质数 p 而言,p 的原根 g 是满足以下条件的正整数:

  • 1<g<p;
  • gp−1modp=1;
  • 对于任意 1≤i<p−1 均有 gimodp=1。

其中 amodp 表示 a 除以 p 的余数。

给出一个整数 a 和质数 p,判断 a 是不是 p 的原根。

保证 1≤T≤20,3≤p≤109,1<a<p,p 为质数。

思路:

要想让 a 是 p 的原根,必须满足三个条件:

  1. 1<a<p ,这条已被约束条件满足了,无需判断;
  2. ap−1modp=1,写个快速幂,O(logn) 就能判断;
  3. 对于任意 1≤i<p−1 均有 aimodp=1,如何判断?

枚举每个 i,依次用快速幂判断,但还是慢了。

正难则反,只需要知道 aimodp=1 的结果,就知道 aimodp=1。

在 [1,p−1) 中,那个 i 可能满足 aimodp=1?

假设 akmodp=1。

∴akmodp=1,ak+1modp=a,ak+2modp=a2modp,…a2kmodp=1,…a3kmodp=1,…axkmodp=1x∈[0,∞]

wow,有周期,每 k 个一循环,每个循环周期大小相等

因为 ap−1modp=1 我们提前判段为错误,并退出了,所以现在的 a 和 p 一定满足 ap−1modp=1。

诶,我们忽略了 0,a0modp=1!

也就是说我们要将 1 到 p−1 划分成若干段长度相同的循环周期,在 [1,p−1) 中,只有每小段的末尾,也就是 p−1 的因数的倍数,可能满足 aimodp=1。

又知道 p−1 的一个因数 x,使得 axmodp=1,那么,这个因数的任意一个倍数 y,也都满足 aymodp=1。

所以只用找 p−1 的每一个因数 x 是否满足 axmodp=1,就可以推出"对于任意 1≤i<p−1 均有 aimodp=1"这个条件了

代码

#include<iostream>
#include<vector>
#define ll long long
using namespace std;
vector<ll>yin;       //表示p-1的因数
ll fpow(ll a,ll b,ll p){//快速幂
	a%=p;
	if(b==1)return a;
	if(b==0)return 1;
	if(b&1)return a*fpow(a*a%p,(b>>1),p)%p;
	return fpow(a*a%p,(b>>1),p);
}
void find_yin(ll x){	//找因数
	while(yin.size())   //清空
		yin.pop_back();    
	for(ll i=2;i*i<=x;i++){
		if(x%i==0){
			yin.push_back(i);
			yin.push_back(x/i);
		}
	}
	return ;
}
void doing(){//求出每次答案
	ll p,a;
	cin>>a>>p;
	if(fpow(a,p-1,p)!=1){  //条件2
		puts("No");
		return ;
	}
	find_yin(p-1);         //找p-1的因数
	for(int i=0;i<yin.size();i++){
		ll y=yin[i];       //枚举每个因数
		if(fpow(a,y,p)==1){//满足条件4(不满足条件3)
			puts("No");
			return ;
		}
	}
	puts("Yes");
	return ;
}
int main(){
	int t; 
	cin>>t;
	while(t--){
		doing();
	}
	return 0;
}

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐