单选
5.将数组{8, 23, 4, 16, 77, -5, 53, 100}中的元素按从大到小的顺序排列,每次可以交换任意两个元素,最少需要交换( )次。
A. 4 B. 5 C. 6 D. 7 E. 8
将某个数向它的目标位置连一条边,那么最终会形成几个环,对某一个有n个点的环,需要n-1步将其变成n个自环,故
这题的图如下
多选
12.计算机在工作过程中,若突然停电,( )中的信息不会丢失。
A. 硬盘 B. CPU C.ROM D. RAM
AC肯定不会丢失,D(内存,包括cache)肯定会丢失。CPU的寄存器好像有断电保持和断电不保持,这里可能把CPU认为是处理信息而不存储信息
数学题
2.书架上有21本书,编号从1到21,从其中选4本,其中每两本的编号都不相邻的选法一共有______种。
方法一:f[i][j]表示前i个位置,放j个球(且有球放在第i个位置上)的方案数,
则
,列表如下,
j\i | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
2 | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
3 | 0 | 0 | 0 | 0 | 1 | 3 | 6 | 10 | 15 | 21 | 28 | 36 | 45 | 55 | 66 | 78 | 91 | 105 | 120 | 136 | 153 |
4 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 4 | 10 | 20 | 35 | 56 | 84 | 120 | 165 | 220 | 286 | 364 | 455 | 560 | 680 |
答案是最后一行的和,3060
方法二:可以看出这个答案是1~15的前缀和的前缀和的前缀和(没错,是三个前缀和),
第一遍前缀和
,
第二遍前缀和
,
下一步化简需要用到二次方和公式,具体推导用
展开来做。
再求前缀和!
,
愉快地用上立方和和平方和公式还有普通求和公式,得到
将n=15带入,得到c[15]=3060
话说公式这种东西一定要反复检查,以我现在的数学水平一遍是不可能算对的
方法三:这题按理说是要用组合数做的
可以把前三本书和他们后面的一个空格绑定起来,或者可以看成用17个空格把4本书隔开,结果就是
看程序写结果
#include<iostream>
using namespace std;
int main()
{
int i, a, b, c, d, f[4];
for(i = 0; i < 4; i++) cin >> f[i];
a = f[0] + f[1] + f[2] + f[3];
a = a / f[0];//把除号看成取模,眼瞎。"/" != "%'!!!
b = f[0] + f[2] + f[3];
b = b / a;//这里也看错
c = (b * f[1] + a) / f[2];
d = f[(b / c ) % 4];
if(f[(a + b + c + d) % 4] > f[2])
cout << a + b<< endl;
else cout << c + d << endl;
return 0;
}
纯手膜,考试的时候一定要多膜几遍!!!一遍绝对做不对!!!
ans=23
#include<iostream>
using namespace std;
void f(int a, int b, int c)
{
cout << a << b << c << ‘/’;
if(a == 3 && b == 2 && c == 1)
return;
if(b < c)
f(a, c, b);
else if(a < b)
{
if(a < c)
f(c, a, b);
else
f(b, c, a);
}
}
int main()
{
int a, b, c;
cin >> a >> b >> c;
f(a, b, c);
cout << endl;
return 0;
}
输入: 1 3 2
(╯°Д°)╯︵ ┻━┻要注意输出最后也是有斜杠的,对于这种写在循环或者跟在某个要多次处理的语句后面的字符,一定要非常小心,不然8分丢不起。
wrong ans = " 132/213/231/312/321"
accepted = “132/213/231/312/321/”
程序填空
1.(找第k大的数) 给定一个长度为1,000,000的无序正整数序列,以及另一个数n(1<=n<=1000000),接下来以类似快速排序的方法找到序列中第n大的数(关于第n大的数:例如序列{1,2,3,4,5,6}中第3大的数是4)。
#include <iostream>
using namespace std;
int a[1000001],n,ans = -1;
void swap(int &a,int &b)
{
int c;
c = a; a = b; b = c;
}
int FindKth(int left, int right, int n)
{
int tmp,value,i,j;
if (left == right) return left;
tmp = rand()% (right - left) + left;
swap(a[tmp],a[left]);
value = ①
i = left;
j = right;
while (i < j)
{
while (i < j && ② ) j --;
if (i < j) {a[i] = a[j]; i ++;} else break;
while (i < j && ③ ) i ++;
if (i < j) {a[j] = a[i]; j --;} else break;
}
④
if (i < n) return FindKth( ⑤ );
if (i > n) return ⑥
return i;
}
int main()
{
int i;
int m = 1000000;
for (i = 1;i <= m;i ++)
cin >> a[i];
cin >> n;
ans = FindKth(1,m,n);
cout << a[ans];
return 0;
}
首先这是一个快拍,但是他的打法非常达克,不是平常经常打的两个指针的,而是填坑的。然后注意是从大到小排序而不是从小到大,和习惯性的思维不同。而且判断大小的时候等于取或不取都是可行的。注意了这几点就可以满分,然而。。。
总结
实际得分:51.5
加上眼瞎扣分,算错扣分,粗心扣分:86
差距有点可怕。真正比赛的时候一定要检查,有时间就一直算吧,反正草稿纸是公家的。