2019年 CSP-S 第一轮(提高级)
// questions
题目预览
若有定义 int a = 7, float x = 2.5, y = 4.7;,则表达式 x + a % 3 * (int) (x + y) % 2 的值是( )
0.0000000.0000000.000000
2.7500002.7500002.750000
2.5000002.5000002.500000
3.5000003.5000003.500000
下列属于图像文件格式的( )
WMV
MPEG
JPEG
AVI
下面哪个选项是 1110111001011111 1011 1001 011111101110010111 和 0101101110101101 0110 1110 101101011011101011 进行逻辑或运算的结果 ( )。
11 1111 1101 111111\ 1111\ 1101\ 111111 1111 1101 1111
11 1111 1111 110111\ 1111\ 1111\ 110111 1111 1111 1101
10 1111 1111 111110\ 1111\ 1111\ 111110 1111 1111 1111
11 1111 1111 111111\ 1111\ 1111\ 111111 1111 1111 1111
编译器的作用是 ( )。
将源程序重新组合
将一种语言(通常是高级语言)翻译成另一种语言(通常是低级语言)
将低级语言翻译成高级语言
将一种编程语言翻译成自然语言
设变量 xxx 为 float 型且已赋值,下列哪条语句能将 xxx 中的数值保留到小数点后两位,并将第三位四舍五入 ( )。
x=(x∗100+0.5)/100.0x = (x*100 + 0.5) / 100.0x=(x∗100+0.5)/100.0
x=(int)(x∗100+0.5)/100.0x = (int)(x*100 + 0.5) / 100.0x=(int)(x∗100+0.5)/100.0
x=(x/100+0.5)∗100.0x = (x / 100 + 0.5) * 100.0x=(x/100+0.5)∗100.0
x=x∗100+0.5/100.0x = x * 100 + 0.5 / 100.0x=x∗100+0.5/100.0
由数字 1,1,2,4,8,81, 1, 2, 4, 8, 81,1,2,4,8,8 组成的不同的 444 位数的个数是 ( )。
104104104
989898
100100100
102102102
排序的算法很多,若按排序的稳定性和不稳定性分类,下面算法中 ( ) 是不稳定排序。
冒泡排序
直接插入排序
快速排序
归并排序
G 是一个非连通无向图(没有重边和自环),共有 282828 条边,则该图至少有 ( ) 个点。
101010
999
111111
888
一些数字可以颠倒过来看,例如 000、111、888 颠倒过来还是本身,666 颠倒过来是 999,999 颠倒过来看还是 666,其他数字颠倒过来都不构成数字。类似的,一些多位数也可以颠倒过来看,比如 106106106 颠倒过来是 901901901。假设某个城市的车牌只由 555 位数字组成,每一位都可以取 000 到 999。请问这个城市最多有多少个车牌倒过来恰好还是原来的车牌,并且车牌上的 555 位数能被 333 整除 ( )。
404040
252525
303030
202020
一次期末考试,某班有 151515 人数学得满分,有 121212 人语文得满分,共有 444 人语文、数学都是满分,那么这个班至少有一门满分的同学有多少人 ( )。
212121
202020
222222
232323
设 A 和 B 是两个长为 n 的有序数组,现在需要将 A 和 B 合并成一个排好序的数组,请问任何以元素比较作为基本运算的归并算法,在最坏情况下至少要做多少次比较( )。
n2n^2n2
nlognn\log nnlogn
2n2n2n
2n−12n - 12n−1
以下哪个结构可以用来存图 ( )。
栈
二叉树
队列
邻接矩阵
以下哪些算法不属于贪心算法 ( )。
Dijkstra 算法
Floyd 算法
Prim 算法
Kruskal 算法
有一个等比数列,共有奇数项,其中第一项和最后一项分别是 222 和 118098118098118098,中间一项是 486486486,请问以下那个数是可能的公比 ( )。
555
333
444
222
由正实数构成的数字三角形排列如图所示,第一行为数字 a1,1a_{1,1}a1,1,第二行的数从左到右依次为 a2,1a_{2,1}a2,1、 a2,2a_{2,2}a2,2,第 nnn 行的数为 an,1a_{n,1}an,1、 an,2…an,na_{n,2}…a_{n,n}an,2…an,n。从 a1,1a_{1,1}a1,1 开始,每一行的数 ai,ja_{i,j}ai,j 只有两条边可以分别通向下一行的两个数 ai+1,ja_{i + 1,j}ai+1,j 和 ai+1,j+1a_{i + 1,j + 1}ai+1,j+1。用动态规划算法找出一条从 a1,1a_{1,1}a1,1 向下通到 an,1a_{n,1}an,1、 an,2…an,na_{n,2}…a_{n,n}an,2…an,n 中的某个路径,使得该路径上的数之和最大。
[图片]
令 C[i][j]C[i][j]C[i][j] 是从 a1,1a_{1,1}a1,1 到 ai,ja_{i,j}ai,j 的路径上的数的最大和,并且 C[i][0]=C[0][j]=0C[i][0] = C[0][j] = 0C[i][0]=C[0][j]=0,则 C[i][j]=C[i][j] =C[i][j]= ( )
max(C[i−1][j−1],C[i−1][j])+ai,j\max(C[i-1][j-1],C[i-1][j])+a_{i,j}max(C[i−1][j−1],C[i−1][j])+ai,j
C[i−1][j−1]+C[i−1][j]C[i-1][j-1]+C[i-1][j]C[i−1][j−1]+C[i−1][j]
max(C[i−1][j−1],C[i−1][j])+1\max(C[i-1][j-1],C[i-1][j])+ 1max(C[i−1][j−1],C[i−1][j])+1
max(C[i][j−1],C[i−1][j])+ai,j\max(C[i][j-1],C[i-1][j])+a_{i,j}max(C[i][j−1],C[i−1][j])+ai,j
阅读程序代码(共 16-21 题共用)
#include <cstdio>
using namespace std;
int n;
int a[100];
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
int ans = 1;
for (int i = 1; i <= n; ++i) {
if (i > 1 && a[i] < a[i - 1])
ans = i;
while (ans < n && a[i] >= a[ans + 1])
++ans;
printf("%d\n", ans);
}
return 0;
}
第 161616 行输出 ansansans 时,ansansans 的值一定大于 iii。
正确
错误
程序输出的 ansansans 小于等于 nnn。
正确
错误
若将第 121212 行的 “<” 改为 “!=” 程序输出的结果不会改变。
正确
错误
当程序执行到第 161616 行时,若 ans−i>2ans - i > 2ans−i>2,则 a[i+1]≤a[i]a[i+1] \le a[i]a[i+1]≤a[i]。
正确
错误
若输入的 aaa 数组是一个严格单调递增的数列,此程序的时间复杂度是
O(logn)\mathcal{O}(\log n)O(logn)
O(n2)\mathcal{O}(n^2)O(n2)
O(nlogn)\mathcal{O}(n\log n)O(nlogn)
O(n)\mathcal{O}(n)O(n)
最坏情况下,此程序的时间复杂度为:
O(n2)\mathcal{O}(n^2)O(n2)
O(logn)\mathcal{O}(\log n)O(logn)
O(n)\mathcal{O}(n)O(n)
O(nlogn)\mathcal{O}(n\log n)O(nlogn)
阅读程序代码(共 22-27 题共用)
#include <iostream>
using namespace std;
const int maxn = 1000;
int n;
int fa[maxn], cnt[maxn];
int getRoot(int v) {
if (fa[v] == v) return v;
return getRoot(fa[v]);
}
int main() {
cin >> n;
for (int i = 0; i < n; ++i) {
fa[i] = i;
cnt[i] = 1;
}
int ans = 0;
for (int i = 0; i < n - 1; ++i) {
int a, b, x, y;
cin >> a >> b;
x = getRoot(a);
y = getRoot(b);
ans += cnt[x] * cnt[y];
fa[x] = y;
cnt[y] += cnt[x];
}
cout << ans << endl;
return 0;
}
输入的 aaa 和 bbb 的值应在 [0,n−1][0, n - 1][0,n−1] 的范围内
正确
错误
第 161616 行改成 fa[i]=0;,不影响程序运行结果
正确
错误
若输入的 aaa 和 bbb 值均在 [0,n−1][0, n-1][0,n−1] 的范围内,则对于任意 0≤i<n0\le i<n0≤i<n,都有 0≤fa[i]<n0 \le fa[i]< n0≤fa[i]<n。
正确
错误
若输入的 aaa 和 bbb 值均在 [0,n−1][0, n-1][0,n−1] 的范围内,则对于任意 0≤i<n0 \le i<n0≤i<n,都有 1≤cnt[i]≤n1\le cnt[i] \le n1≤cnt[i]≤n。
正确
错误
当 nnn 等于 505050 时,若 aaa、bbb 的值都在 [0,49][0,49][0,49] 的范围内,且在第 252525 行时 xxx总是不等于 yyy,那么输出为 ( )
1276
1176
1225
1250
此程序的时间复杂度是( )
O(n)\mathcal{O}(n)O(n)
O(logn)\mathcal{O}(\log n)O(logn)
O(n2)\mathcal{O}(n^2)O(n2)
O(nlogn)\mathcal{O}(n\log n)O(nlogn)
阅读程序代码(共 28-33 题共用)
#include <iostream>
#include <string>
using namespace std;
const int max1 = 202;
string s, t;
int pre[max1], suf[max1];
int main() {
cin >> s >> t;
int slen = s.length(), tlen= t.length();
for (int i = 0, j = 0; i < slen; ++i) {
if (j < tlen && s[i] == t[j]) ++j;
pre[i] = j;// t[0..j-1]是s[0..i]的子序列
}
for (int i = slen - 1, j = tlen - 1; i >= 0; --i) {
if(j >= 0 && s[i] == t[j]) --j;
suf[i]= j; //t[j+1..tlen-1]是s[i..slen-1]的子序列
}
suf[slen] = tlen -1;
int ans = 0;
for (int i = 0, j = 0, tmp= 0; i <= slen; ++i) {
while (j <= slen && tmp >= suf[j] + 1) ++j;
ans = max(ans, j - i - 1);
tmp = pre[i];
}
cout << ans << endl;
return 0;
}
本题t是s的子序列的意思是:从s中删去若干个字符,可以得到t。特别的,如果s = t,那么t也是s的子序列;空串是任何串的子序列。例如“acd”是“abcde”的子序列,“acd”是“acd”的子序列,但“adc”不是“abcde”的子序列。
S[x..y]表示s[x]…s[y]共 y−x+1y-x+1y−x+1 个字符构成的字符串,若 x>yx>yx>y 则s[x..y]是空串。t[x..y]同理。
提示:
t[0..pre[i]-1]是s[0..i]的子序列;
t[suf[i]+1..tlen-1]是s[i..slen-1]的子序列。
程序输出时,suf数组满足:对任意 0≤i<slen0 \le i<slen0≤i<slen,suf[i]≤suf[i+1]suf[i] \le suf[i+1]suf[i]≤suf[i+1]。
正确
错误
本题t是s的子序列的意思是:从s中删去若干个字符,可以得到t。特别的,如果s = t,那么t也是s的子序列;空串是任何串的子序列。例如“acd”是“abcde”的子序列,“acd”是“acd”的子序列,但“adc”不是“abcde”的子序列。
S[x..y]表示s[x]…s[y]共 y−x+1y-x+1y−x+1 个字符构成的字符串,若 x>yx>yx>y 则s[x..y]是空串。t[x..y]同理。
提示:
t[0..pre[i]-1]是s[0..i]的子序列;
t[suf[i]+1..tlen-1]是s[i..slen-1]的子序列。
当 t 是 s 的子序列时,输出一定不为 000。
正确
错误
本题t是s的子序列的意思是:从s中删去若干个字符,可以得到t。特别的,如果s = t,那么t也是s的子序列;空串是任何串的子序列。例如“acd”是“abcde”的子序列,“acd”是“acd”的子序列,但“adc”不是“abcde”的子序列。
S[x..y]表示s[x]…s[y]共 y−x+1y-x+1y−x+1 个字符构成的字符串,若 x>yx>yx>y 则s[x..y]是空串。t[x..y]同理。
提示:
t[0..pre[i]-1]是s[0..i]的子序列;
t[suf[i]+1..tlen-1]是s[i..slen-1]的子序列。
程序运行到第 232323 行时,j - i- 1 一定不小于 000
正确
错误
本题t是s的子序列的意思是:从s中删去若干个字符,可以得到t。特别的,如果s = t,那么t也是s的子序列;空串是任何串的子序列。例如“acd”是“abcde”的子序列,“acd”是“acd”的子序列,但“adc”不是“abcde”的子序列。
S[x..y]表示s[x]…s[y]共 y−x+1y-x+1y−x+1 个字符构成的字符串,若 x>yx>yx>y 则s[x..y]是空串。t[x..y]同理。
提示:
t[0..pre[i]-1]是s[0..i]的子序列;
t[suf[i]+1..tlen-1]是s[i..slen-1]的子序列。
当 t 是 s 的子序列时,pre 数组和 suf 数组满足:对任意 0≤i<slen0\le i<slen0≤i<slen,pre[i]>suf[i+1]pre[i]>suf[i+1]pre[i]>suf[i+1]。
正确
错误
本题t是s的子序列的意思是:从s中删去若干个字符,可以得到t。特别的,如果s = t,那么t也是s的子序列;空串是任何串的子序列。例如“acd”是“abcde”的子序列,“acd”是“acd”的子序列,但“adc”不是“abcde”的子序列。
S[x..y]表示s[x]…s[y]共 y−x+1y-x+1y−x+1 个字符构成的字符串,若 x>yx>yx>y 则s[x..y]是空串。t[x..y]同理。
提示:
t[0..pre[i]-1]是s[0..i]的子序列;
t[suf[i]+1..tlen-1]是s[i..slen-1]的子序列。
若 tlen = 10,输出为 000 ,则 slen 最小为:
101010
121212
000
111
本题t是s的子序列的意思是:从s中删去若干个字符,可以得到t。特别的,如果s = t,那么t也是s的子序列;空串是任何串的子序列。例如“acd”是“abcde”的子序列,“acd”是“acd”的子序列,但“adc”不是“abcde”的子序列。
S[x..y]表示s[x]…s[y]共 y−x+1y-x+1y−x+1 个字符构成的字符串,若 x>yx>yx>y 则s[x..y]是空串。t[x..y]同理。
提示:
t[0..pre[i]-1]是s[0..i]的子序列;
t[suf[i]+1..tlen-1]是s[i..slen-1]的子序列。
若 tlen = 10, 输出为 222,则 slen 最小为
000
101010
121212
111
阅读程序代码(共 34-38 题共用)
#include<cstdio>
using namespace std;
const int maxn = 1001;
int n;
int cnt[maxn];
int child [maxn][maxn];
int unlock[maxn];
int points;
int threshold[maxn],bonus[maxn];
bool find(){
int target=-1;
for (int i = 1;i<=n;++i)
if(① && ②){
target = i;
break;
}
if(target==-1)
return false;
unlock[target]=-1;
③
for (int i=0;i<cnt[target];++i)
④
return true;
}
int main(){
scanf("%d%d",&n, &points);
for (int i =1; i<=n;++i){
cnt [i]=0;
scanf("%d%d",&threshold[i],&bonus[i]);
}
for (int i=1;i<=n;++i){
int m;
scanf("%d",&m);
⑤
for (int j=0; j<m ;++j){
int fa;
scanf("%d", &fa);
child [fa][cnt[fa]]=i;
++cnt[fa];
}
}
int ans = 0;
while(find())
++ans;
printf("%d\n", ans);
return 0;
}
(匠人的自我修养)一个匠人决定要学习 nnn 个新技术,要想成功学习一个新技术,他不仅要拥有一定的经验值,而且还必须要先学会若干个相关的技术。学会一个新技术之后,他的经验值会增加一个对应的值。给定每个技术的学习条件和习得后获得的经验值,给定他已有的经验值,请问他最多能学会多少个新技术。
输入第一行有两个数,分别为新技术个数 n(1≤n≤103)n(1 \leq n \leq 10^3)n(1≤n≤103),以及已有经验值 (≤107)(\leq 10^7)(≤107)。
接下来 nnn 行。第 iii 行的两个正整数,分别表示学习第 iii 个技术所需的最低经验值 (≤107)(\leq 10^7)(≤107),以及学会第 iii 个技术后可获得的经验值 (≤104)(\leq 10^4)(≤104)。
接下来 nnn 行。第 iii 行的第一个数 mi(0≤mi<n)m_i(0 \leq m_i < n)mi(0≤mi<n),表示第 iii 个技术的相关技术数量。紧跟着 mmm 个两两不同的数,表示第 iii 个技术的相关技术编号,输出最多能学会的新技术个数。
下面的程序以 O(n2)O(n^2)O(n2)的时间复杂度完成这个问题,试补全程序。
请选择 ① 应该填写的代码
unlock[i]<=0
unlock[i]>=0
unlock[i]==0
unlock[i]==-1
(匠人的自我修养)一个匠人决定要学习 nnn 个新技术,要想成功学习一个新技术,他不仅要拥有一定的经验值,而且还必须要先学会若干个相关的技术。学会一个新技术之后,他的经验值会增加一个对应的值。给定每个技术的学习条件和习得后获得的经验值,给定他已有的经验值,请问他最多能学会多少个新技术。
输入第一行有两个数,分别为新技术个数 n(1≤n≤103)n(1 \leq n \leq 10^3)n(1≤n≤103),以及已有经验值 (≤107)(\leq 10^7)(≤107)。
接下来 nnn 行。第 iii 行的两个正整数,分别表示学习第 iii 个技术所需的最低经验值 (≤107)(\leq 10^7)(≤107),以及学会第 iii 个技术后可获得的经验值 (≤104)(\leq 10^4)(≤104)。
接下来 nnn 行。第 iii 行的第一个数 mi(0≤mi<n)m_i(0 \leq m_i < n)mi(0≤mi<n),表示第 iii 个技术的相关技术数量。紧跟着 mmm 个两两不同的数,表示第 iii 个技术的相关技术编号,输出最多能学会的新技术个数。
下面的程序以 O(n2)O(n^2)O(n2)的时间复杂度完成这个问题,试补全程序。
请选择 ② 应该填写的代码
threshold[i]>points
threshold[i]>=points
points>threshold[i]
points>=threshold[i]
(匠人的自我修养)一个匠人决定要学习 nnn 个新技术,要想成功学习一个新技术,他不仅要拥有一定的经验值,而且还必须要先学会若干个相关的技术。学会一个新技术之后,他的经验值会增加一个对应的值。给定每个技术的学习条件和习得后获得的经验值,给定他已有的经验值,请问他最多能学会多少个新技术。
输入第一行有两个数,分别为新技术个数 n(1≤n≤103)n(1 \leq n \leq 10^3)n(1≤n≤103),以及已有经验值 (≤107)(\leq 10^7)(≤107)。
接下来 nnn 行。第 iii 行的两个正整数,分别表示学习第 iii 个技术所需的最低经验值 (≤107)(\leq 10^7)(≤107),以及学会第 iii 个技术后可获得的经验值 (≤104)(\leq 10^4)(≤104)。
接下来 nnn 行。第 iii 行的第一个数 mi(0≤mi<n)m_i(0 \leq m_i < n)mi(0≤mi<n),表示第 iii 个技术的相关技术数量。紧跟着 mmm 个两两不同的数,表示第 iii 个技术的相关技术编号,输出最多能学会的新技术个数。
下面的程序以 O(n2)O(n^2)O(n2)的时间复杂度完成这个问题,试补全程序。
请选择 ③ 应该填写的代码
target = -1
–cnt[target]
bonus[target] = 0
points += bonus[target]
(匠人的自我修养)一个匠人决定要学习 nnn 个新技术,要想成功学习一个新技术,他不仅要拥有一定的经验值,而且还必须要先学会若干个相关的技术。学会一个新技术之后,他的经验值会增加一个对应的值。给定每个技术的学习条件和习得后获得的经验值,给定他已有的经验值,请问他最多能学会多少个新技术。
输入第一行有两个数,分别为新技术个数 n(1≤n≤103)n(1 \leq n \leq 10^3)n(1≤n≤103),以及已有经验值 (≤107)(\leq 10^7)(≤107)。
接下来 nnn 行。第 iii 行的两个正整数,分别表示学习第 iii 个技术所需的最低经验值 (≤107)(\leq 10^7)(≤107),以及学会第 iii 个技术后可获得的经验值 (≤104)(\leq 10^4)(≤104)。
接下来 nnn 行。第 iii 行的第一个数 mi(0≤mi<n)m_i(0 \leq m_i < n)mi(0≤mi<n),表示第 iii 个技术的相关技术数量。紧跟着 mmm 个两两不同的数,表示第 iii 个技术的相关技术编号,输出最多能学会的新技术个数。
下面的程序以 O(n2)O(n^2)O(n2)的时间复杂度完成这个问题,试补全程序。
请选择 ④ 应该填写的代码
cnt[child[target][i]] -= 1
cnt[child[target][i]] = 0
unlock[child[target][i]] -= 1
unlock[child[target][i]] = 0
(匠人的自我修养)一个匠人决定要学习 nnn 个新技术,要想成功学习一个新技术,他不仅要拥有一定的经验值,而且还必须要先学会若干个相关的技术。学会一个新技术之后,他的经验值会增加一个对应的值。给定每个技术的学习条件和习得后获得的经验值,给定他已有的经验值,请问他最多能学会多少个新技术。
输入第一行有两个数,分别为新技术个数 n(1≤n≤103)n(1 \leq n \leq 10^3)n(1≤n≤103),以及已有经验值 (≤107)(\leq 10^7)(≤107)。
接下来 nnn 行。第 iii 行的两个正整数,分别表示学习第 iii 个技术所需的最低经验值 (≤107)(\leq 10^7)(≤107),以及学会第 iii 个技术后可获得的经验值 (≤104)(\leq 10^4)(≤104)。
接下来 nnn 行。第 iii 行的第一个数 mi(0≤mi<n)m_i(0 \leq m_i < n)mi(0≤mi<n),表示第 iii 个技术的相关技术数量。紧跟着 mmm 个两两不同的数,表示第 iii 个技术的相关技术编号,输出最多能学会的新技术个数。
下面的程序以 O(n2)O(n^2)O(n2)的时间复杂度完成这个问题,试补全程序。
请选择 ⑤ 应该填写的代码
unlock[i] = cnt[i]
unlock[i] = m
unlock[i] = 0
unlock[i] =-1
阅读程序代码(共 39-43 题共用)
#include <cstdio>
#include<algorithm>
using namespace std ;
const int maxn =64;
int n,m;
int a[maxn], b[maxn];
unsigned long long status, trans;
bool win;
int main() {
scanf(“%d%d”,&n, &m);
for (int i = 0; i < n; ++i)
scanf(“%d%d”, &a[i], &b[i]);
for (int i = 0; i < n; ++i)
for (int j = i + 1; j < n; ++j)
if (a[i] > a[j]) {
swap(a[i], a[j]);
swap(b[i], b[j]);
}
status = ①;
trans = 0;
for (int i = 1, j = 0; i <= m; ++i) {
while (j < n && ②) {
③;
++j;
}
win = ④;
⑤;
}
puts(win ? “Win” : “Loss”);
return 0;
}
(取石子)Alice 和 Bob 两个人在玩取石子游戏,他们制定了 nnn 条取石子的规则,第 iii 条规则为:如果剩余的石子个数大于等于 a[i]a[i]a[i] 且大于等于 b[i]b[i]b[i],那么她们可以取走 b[i]b[i]b[i] 个石子。他们轮流取石子。如果轮到某个人取石子,而他无法按照任何规则取走石子,那么他就输了,一开始石子有 mmm 个。请问先取石子的人是否有必胜的方法?
输入第一行有两个正整数,分别为规则个数 n(1≤n≤64)n ( 1 \leq n \leq 64)n(1≤n≤64),以及石子个数 m(≤107)m(\leq 10^7)m(≤107)。
接下来 nnn 行。第i行有两个正整数 a[i]a[i]a[i] 和 b[i]b[i]b[i]。1≤a[i]≤107,b[i]≤641 \leq a[i] \leq 10^7, b[i] \leq 641≤a[i]≤107,b[i]≤64
如果先取石子的人必胜,那么输出“Win”,否则输出“Loss”
提示:
可以使用动态规划解决这个问题。由于 b[i]b[i]b[i] 不超过 646464,所以可以使用64位无符号整数去压缩必要的状态。
Status 是胜负状态的二进制压缩,trans 是状态转移的二进制压缩。
代码说明:
“~”表示二进制补码运算符,它将每个二进制位的 000 变成 111、111 变为 000;
而“^”表示二进制异或运算符,它将两个参与运算的数重的每个对应的二进制位一一进行比较,若两个二进制位相同,则运算结果的对应二进制位为 000,反之为 111。
ull 标识符表示它前面的数字是 unsigned long long 类型。
试补全程序
请选择 ① 应该填写的代码
0
~0ull
~0ull^1
1
(取石子)Alice 和 Bob 两个人在玩取石子游戏,他们制定了 nnn 条取石子的规则,第 iii 条规则为:如果剩余的石子个数大于等于 a[i]a[i]a[i] 且大于等于 b[i]b[i]b[i],那么她们可以取走 b[i]b[i]b[i] 个石子。他们轮流取石子。如果轮到某个人取石子,而他无法按照任何规则取走石子,那么他就输了,一开始石子有 mmm 个。请问先取石子的人是否有必胜的方法?
输入第一行有两个正整数,分别为规则个数 n(1≤n≤64)n ( 1 \leq n \leq 64)n(1≤n≤64),以及石子个数 m(≤107)m(\leq 10^7)m(≤107)。
接下来 nnn 行。第i行有两个正整数 a[i]a[i]a[i] 和 b[i]b[i]b[i]。1≤a[i]≤107,b[i]≤641 \leq a[i] \leq 10^7, b[i] \leq 641≤a[i]≤107,b[i]≤64
如果先取石子的人必胜,那么输出“Win”,否则输出“Loss”
提示:
可以使用动态规划解决这个问题。由于 b[i]b[i]b[i] 不超过 646464,所以可以使用64位无符号整数去压缩必要的状态。
Status 是胜负状态的二进制压缩,trans 是状态转移的二进制压缩。
代码说明:
“~”表示二进制补码运算符,它将每个二进制位的 000 变成 111、111 变为 000;
而“^”表示二进制异或运算符,它将两个参与运算的数重的每个对应的二进制位一一进行比较,若两个二进制位相同,则运算结果的对应二进制位为 000,反之为 111。
ull 标识符表示它前面的数字是 unsigned long long 类型。
试补全程序
请选择 ② 应该填写的代码
a[j]< i
a[j] ==i
a[j] !=i
a[j] >i
(取石子)Alice 和 Bob 两个人在玩取石子游戏,他们制定了 nnn 条取石子的规则,第 iii 条规则为:如果剩余的石子个数大于等于 a[i]a[i]a[i] 且大于等于 b[i]b[i]b[i],那么她们可以取走 b[i]b[i]b[i] 个石子。他们轮流取石子。如果轮到某个人取石子,而他无法按照任何规则取走石子,那么他就输了,一开始石子有 mmm 个。请问先取石子的人是否有必胜的方法?
输入第一行有两个正整数,分别为规则个数 n(1≤n≤64)n ( 1 \leq n \leq 64)n(1≤n≤64),以及石子个数 m(≤107)m(\leq 10^7)m(≤107)。
接下来 nnn 行。第i行有两个正整数 a[i]a[i]a[i] 和 b[i]b[i]b[i]。1≤a[i]≤107,b[i]≤641 \leq a[i] \leq 10^7, b[i] \leq 641≤a[i]≤107,b[i]≤64
如果先取石子的人必胜,那么输出“Win”,否则输出“Loss”
提示:
可以使用动态规划解决这个问题。由于 b[i]b[i]b[i] 不超过 646464,所以可以使用64位无符号整数去压缩必要的状态。
Status 是胜负状态的二进制压缩,trans 是状态转移的二进制压缩。
代码说明:
“~”表示二进制补码运算符,它将每个二进制位的 000 变成 111、111 变为 000;
而“^”表示二进制异或运算符,它将两个参与运算的数重的每个对应的二进制位一一进行比较,若两个二进制位相同,则运算结果的对应二进制位为 000,反之为 111。
ull 标识符表示它前面的数字是 unsigned long long 类型。
试补全程序
请选择 ③ 应该填写的代码
trans |= 1ull <<(b[j] - 1)
status |=1ull << (b[j]- 1)
status +=1ull << (b[j]-1)
trans +=1ull<< (b[j]-1)
(取石子)Alice 和 Bob 两个人在玩取石子游戏,他们制定了 nnn 条取石子的规则,第 iii 条规则为:如果剩余的石子个数大于等于 a[i]a[i]a[i] 且大于等于 b[i]b[i]b[i],那么她们可以取走 b[i]b[i]b[i] 个石子。他们轮流取石子。如果轮到某个人取石子,而他无法按照任何规则取走石子,那么他就输了,一开始石子有 mmm 个。请问先取石子的人是否有必胜的方法?
输入第一行有两个正整数,分别为规则个数 n(1≤n≤64)n ( 1 \leq n \leq 64)n(1≤n≤64),以及石子个数 m(≤107)m(\leq 10^7)m(≤107)。
接下来 nnn 行。第i行有两个正整数 a[i]a[i]a[i] 和 b[i]b[i]b[i]。1≤a[i]≤107,b[i]≤641 \leq a[i] \leq 10^7, b[i] \leq 641≤a[i]≤107,b[i]≤64
如果先取石子的人必胜,那么输出“Win”,否则输出“Loss”
提示:
可以使用动态规划解决这个问题。由于 b[i]b[i]b[i] 不超过 646464,所以可以使用64位无符号整数去压缩必要的状态。
Status 是胜负状态的二进制压缩,trans 是状态转移的二进制压缩。
代码说明:
“~”表示二进制补码运算符,它将每个二进制位的 000 变成 111、111 变为 000;
而“^”表示二进制异或运算符,它将两个参与运算的数重的每个对应的二进制位一一进行比较,若两个二进制位相同,则运算结果的对应二进制位为 000,反之为 111。
ull 标识符表示它前面的数字是 unsigned long long 类型。
试补全程序
请选择 ④ 应该填写的代码
~status | trans
status & trans
status | trans
~status & trans
(取石子)Alice 和 Bob 两个人在玩取石子游戏,他们制定了 nnn 条取石子的规则,第 iii 条规则为:如果剩余的石子个数大于等于 a[i]a[i]a[i] 且大于等于 b[i]b[i]b[i],那么她们可以取走 b[i]b[i]b[i] 个石子。他们轮流取石子。如果轮到某个人取石子,而他无法按照任何规则取走石子,那么他就输了,一开始石子有 mmm 个。请问先取石子的人是否有必胜的方法?
输入第一行有两个正整数,分别为规则个数 n(1≤n≤64)n ( 1 \leq n \leq 64)n(1≤n≤64),以及石子个数 m(≤107)m(\leq 10^7)m(≤107)。
接下来 nnn 行。第i行有两个正整数 a[i]a[i]a[i] 和 b[i]b[i]b[i]。1≤a[i]≤107,b[i]≤641 \leq a[i] \leq 10^7, b[i] \leq 641≤a[i]≤107,b[i]≤64
如果先取石子的人必胜,那么输出“Win”,否则输出“Loss”
提示:
可以使用动态规划解决这个问题。由于 b[i]b[i]b[i] 不超过 646464,所以可以使用64位无符号整数去压缩必要的状态。
Status 是胜负状态的二进制压缩,trans 是状态转移的二进制压缩。
代码说明:
“~”表示二进制补码运算符,它将每个二进制位的 000 变成 111、111 变为 000;
而“^”表示二进制异或运算符,它将两个参与运算的数重的每个对应的二进制位一一进行比较,若两个二进制位相同,则运算结果的对应二进制位为 000,反之为 111。
ull 标识符表示它前面的数字是 unsigned long long 类型。
试补全程序
请选择 ⑤ 应该填写的代码
trans = status | trans ^win
status = trans >> 1^win
trans = status ^trans |win
status =status <<1^win