目录

Day 1

上午 9:00 - 11:00,摸底测试

T1:弹跳蚱蜢

题目描述

输入格式

输出格式

输入样例

输出样例

样例解释

解析

T2:弗林特船长漂流记

题目描述

输入格式

输出格式

样例

样例输入

解析:

T3 网球比赛

题目描述

输入格式

输出格式

样例

样例输入

样例输出

样例解释

解析:

T4 放置羊群

题目描述

输入格式

输出格式

样例

样例输入

样例输出

下午:分治算法(1)

概念:

特征(四“可”):

求解步骤:

分治思想的基础应用:

循环比赛

题目描述

输入格式

输出格式

样例

样例输入

样例输出

解析:

分治中的快速排序:

算法说明:

图片及文字举例:

代码:

分治中的归并排序:

归并与快排的区别:

代码:

小结:


Day 1

上午 9:00 - 11:00,摸底测试

T1:弹跳蚱蜢

时间限制:1000ms       空间限制:256MB

输入文件:jump.in 输出文件:jump.out

题目描述

现在,有一只蚱蜢位于一个数轴上x0 处。

因为它无事可做,便灵机一动,开始在数轴上进行弹跳训练。因为蚱蜢非常喜欢正整数,因此,在最开 始的第一分钟,它会向前跳1个单位的长度,在第二分钟,它会向前跳2个单位的长度,以此类推。而蚱 蜢觉得一直的往前跳跃也没啥意思,因此,它规定,如果在这一次跳跃前,它处于的点坐标为偶数,那 么,它就会向左跳,否则,它才会向右跳。

例如:如果在连续的18次跳跃之后,蚱蜢到达了坐标点7,在它进行第19次跳跃时,因为它当前所处的 位置是奇数,所以,它会往右跳跃19个单位长度到达坐标点19+7=26。在它进行第20次跳跃时,因为当 前所处的坐标点26是偶数,所以,它会向左跳跃20个单位长度到达坐标点26-20=6.

现在,已知蚱蜢最初始的坐标点 的大小,请你求出当蚱蜢跳跃 次以后到达的位置。

输入格式

第一行输入一个数字t(1 ≤ t ≤ 1e4) ,表示样例的测试数量。

接下来 行,每行两个数字,第一个数字x0(-1e14 ≤ x0 ≤ 1e14) ,表示蚱蜢的初始位置,第二个数字 n(1 ≤ t ≤ 1e14),表示跳跃的次数。

输出格式

对于每一个问题,输出跳跃n次后到达的坐标点位置。

输入样例

9

0 1

0 2

10 10

10 99

177 13

10000000000 987654321

-433494437 87178291199

1 0

-1 1

输出样例

-1

1

11

110

190

90

12345679

-87611785637

1

0

样例解释

解析

对于第一个问题。蚱蜢的初始位置在坐标0处,因为0是一个偶数,因此,蚱蜢首先会向左跳1个单位长度,因此第一个问题的答案为-1.

对于第二个问题,蚱蜢的初始位置在坐标0初,因为0是一个偶数,因此,第一次向左跳一个单位长度到 达-1,因为-1是一个奇数,因此,第二次向右跳2到达坐标点1,得到答案。

很容易,我们根据题意模拟,即可得到以下代码:

#include <bits/stdc++.h>
using namespace std;
int T;
long long x, n;
int main() {scanf("%d", &T);while(T--) {scanf("%lld%lld", &x, &n);for (int i = 1;i <= n;i++) {if (x & 1) {x += i;} else {x -= i;}}printf("%lld\n", x);}return 0;
} 

注意:

(1)x 一定要定义成长整型(long long int)。

(2)“x & 1”中‘&’是位运算,这里是用于判断x是否能被2整除。

那么,恭喜你,TLE,0分。

那么,如何优化呢?

找规律!

顺便说说,如何更快更准更高级的找规律。

首先,你需要一个暴力程序,和一个数据生成程序。

如下:

暴力程序:

#include <bits/stdc++.h>
using namespace std;
int T;
long long x, n;
int main() {freopen("1.in", "r", stdin);freopen("1.out", "w", stdout);scanf("%d", &T);while(T--) {scanf("%lld%lld", &x, &n);for (int i = 1;i <= n;i++) {if (x & 1) {x += i;} else {x -= i;}}printf("%lld\n", x);}return 0;
} 

很显然,我们应该从起点为奇数和起点为偶数开始分别找规律。

数据生成程序:

1.偶数:

#include <bits/stdc++.h>
using namespace std;
int main() {freopen("1.in", "w", stdout);int T = 20;cout << 20 << endl;while(T--) {cout << 0 << " " << 20 - T << endl;}return 0;
}

所以,输入数据:

20
0 1
0 2
0 3
0 4
0 5
0 6
0 7
0 8
0 9
0 10
0 11
0 12
0 13
0 14
0 15
0 16
0 17
0 18
0 19
0 20

输出数据:

-1
1
4
0
-5
1
8
0
-9
1
12
0
-13
1
16
0
-17
1
20
0

2.奇数:

#include <bits/stdc++.h>
using namespace std;
int main() {freopen("1.in", "w", stdout);int T = 20;cout << 20 << endl;while(T--) {cout << 1 << " " << 20 - T << endl;}return 0;
}

所以,输入数据:

20
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
1 11
1 12
1 13
1 14
1 15
1 16
1 17
1 18
1 19
1 20

输出数据:

2
0
-3
1
6
0
-7
1
10
0
-11
1
14
0
-15
1
18
0
-19
1

这不,规律出来了。

#include <bits/stdc++.h>
using namespace std;
long long T, x, n, xx;
int main() {//freopen("jump.in", "r", stdin);//freopen("jump.out", "w", stdout);scanf("%lld", &T);while(T--) {scanf("%lld%lld", &x, &n);long long xxx = abs(x);if (xxx % 2 == 1) {//cout << "B";if (n % 4 == 1) {xx = n;} else if (n % 4 == 2) {xx = -1;} else if (n % 4 == 3) {xx = -1 * n - 1;} else {xx = 0;}} else {if (n % 4 == 1) {xx = -1 * n;} else if (n % 4 == 2) {xx = 1;} else if (n % 4 == 3) {xx = n + 1;} else {xx = 0;}}//cout << x << " " << xx << endl;printf("%lld\n", x + xx);}return 0;
} 

AC!47ms

T2:弗林特船长漂流记

内存限制:256 MiB时间限制:2000 ms

题目描述

弗林特船长和他的船员近几个月来一直在野蛮海域漂流,喝着朗姆酒,讲述自己的故事。这个时候,波格丹叔叔总是会提起自己的侄子丹尼斯,讲述丹尼斯是如何帮助他解决一个有一个难题的。

一开始,波格丹叔叔在黑板上写下了一个正整数,这个正整数由个数字组成。在那以后,他擦掉了x,改为了整数k,而这个数字就是数字用二进制表示串联在一起的。比如,假设x=729,那么k = 111101001(因为7 = 111, 2 = 10, 9 = 1001)

可是,波格丹叔叔的脑袋瓜不太灵光,他并不知道怎样对x进行处理,因此,他请丹尼斯来帮忙,丹尼斯看后发现,他需要删除数字k最后的n个数字,将这个新的数字命名为r,然后找到这个长度为n的整数x,使得r(作为数字)最大。如果有多个满足条件的x,选择最小的那一个。

这时,在座的所有人都对这个问题充满兴趣,请你也来尝试尝试,帮助波格丹叔叔解决这个问题。

注意:在这个任务中,我们将所有的整数(不管是或者)​,都当做数字进行比较。所以,729 < 1999, 111<1000.

输入格式

第一行输入一个数字,表示测试的数量

接下来行,每行输入一个数字,表示原始数字的长度和数字变为需要删去的位数。

输出格式

对于每组测试,输出一个位数字,表示满足最大的最小的位数。

样例

样例输入

复制2
1
3

样例输出

复制8
998

解析:

细读题目,你会发现数字的构成,只有两种9(1001),8(1000),全是4位,7(111)为什么不行,因为只有3位。

n=1时,9,8均可,选最小,那么x = 8(1000)

n=2时,99,98均可,选最小,那么x = 98(10011000)

n=3时,999,998均可,选最小,那么x = 998(100110011000)

n=4时,9999,9998均可,选最小,那么x = 9998(1001100110011000)

n=5时,99999,99998,99988均可,选最小,那么x = 99988(10011001100110001000)

n=6时,999999,999998,999988均可,选最小,那么x = 999988(100110011001100110001000)

#include <bits/stdc++.h>
using namespace std;
int T, n, b, c;
int main() {scanf("%d", &T);while (T--) {scanf("%d", &n);b = (n + 3) / 4;c = n - b;for (int i = 1; i <= c; i++) printf("9");for (int i = 1; i <= b; i++) printf("8");puts("");}return 0;
}

AC!147ms

T3 网球比赛

内存限制:256 MiB时间限制:2000 ms

题目描述

爱丽丝和鲍勃正在打网球。

在网球比赛中,爱丽丝和鲍勃将进行轮流发球,即如果第一局由爱丽丝发球,那么第二局将由鲍勃发球,反之亦然。

在一句网球比赛中,如果没有发球的那一方取得了本局比赛的胜利,那么,我们将称这一局为破发局。

现在,已知爱丽丝共赢得局比赛,鲍勃共赢的局比赛,但并不知道两人谁先发球,谁赢得了第几场比赛。

现在,请你计算并输出所有的可能的破发局数量。

输入格式

第一行输入一个数字t(1≤t≤1e3),表示测试的数量。

接下来行,每行两个数字a和b(0≤a,b≤1e5),分别表示爱丽丝和鲍勃赢得的局数。

输出格式

对于每组测试,分别输出两行内容。

第一行输出一个数字m,表示可能的破发局数量。

第二行输出个数字m,列举出所有情况的破发局数量。

样例

样例输入

复制3
2 1
1 1
0 5

样例输出

复制4
0 1 2 3
2
0 2
2
2 3

样例解释

对于第一组样例,可能出现

爱丽丝保住发球局,鲍勃保住发球局,爱丽丝保住发球局,破发局数为0

鲍勃保住发球局,爱丽丝保住发球局,爱丽丝破发,破发局数为1

鲍勃破发,爱丽丝破发,爱丽丝保住发球局,破发局数为2

爱丽丝破发,鲍勃破发,爱丽丝破发,破发局数为3

解析:

此题,本人现在还没想懂,先咕一下。

T4 放置羊群

内存限制:256 MiB时间限制:1000 ms

题目描述

现在,你正在玩一个名为放置羊群的游戏,这个游戏的最终目标是需要你将所有的绵羊排成连续的一排。在一个游戏关卡中,你将得到一个长度为的字符串。这个字符串由字符'.'和字符'*'组成,其中,'.'表示空格,'*‘表示绵羊。如果对应的位置上存在空格,那么,你每一次可以将一只绵羊任意的向左或向右移动一格的位置。

例如:如果现在有一组,字符串为“**.*..”的数据,那么,你将可以对其进行以下操作:

先将第4个格子内的绵羊向右移动一格,得到“**..*.”

再将第2个格子内的绵羊向右移动一格,得到“*.*.*.”

再将第1个格子内的绵羊向右移动一格,得到“.**.*.”

再将第3个格子内的绵羊向右移动一格,得到“.*.**.”

再将第2个格子内的绵羊向右移动一格,得到“..***.”

此时,所有的绵羊都已排成连续的一排,游戏结束。

现在,题目将告诉你每个关卡的情况,请你计算,通过这个关卡最少需要移动多少次?

输入格式

第一行输入一个数字表示测试的组数。

对于每组测试,第一行输入一个数字,表示字符串的长度。第二行输入一个只包含'.'和'*'的字符串。

题目保证,对于任何的一个测试文件,的和不超过

输出格式

对于任何一场游戏,输出通关最少所需要移动的次数。

样例

样例输入

复制5
6
**.*..
5
*****
3
.*.
3
...
10
*.*...*.**

样例输出

复制1
0
0
0
9

初一数学中,有个”奇点偶段“定理(假设有一个数轴,数轴上的点到中间点(段)的距离之和最小)

那这题只需要先找到 在所有 * 处于中间位置的 * ,然后遍历计算;

因为*移动会受到其他*的限制,所以距离还要减去目标和终点之间*的个数;

#include <bits/stdc++.h>
using namespace std;
int T,n, mid, a[1000005];
long long sum;
string s;
int main() {cin >> T;while (T--) {cin >> n;cin >> s;int cnt = 0;for (int i = 0; i < n; i++) {if (s[i] == '*') a[cnt++] = i;}mid = cnt / 2;for (int i = 0; i < cnt; i++) {sum += abs(a[mid] - a[i]) - abs(mid - i);}cout << sum << endl;}return 0;
}

下午:分治算法(1)

概念:

对于一个规模为n的问题:若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。 这种算法设计策略叫做分治法。

特征(四“可”):

(1)该问题的规模缩小到一定的程度就可以容易地解决(简化:可解)。

(2)该问题可以分解为若干个规模较小的相同问题(简化:可分)。

(3)利用该问题分解出的子问题的解可以合并为该问题的解(简化:可合)。

(4)该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题(简化:可独)。

求解步骤:

1.分:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题。

2.求:若子问题规模较小而容易被解决则直接求解,否则递归地求解各个子问题。

3.合:将各个子问题的解合并为原问题的解。

分治思想的基础应用:

循环比赛

内存限制:256 MiB时间限制:1000 ms

题目描述

在修罗王和邪狼亡命天涯的同时,魔法学院一年一度的运动会正开的如火如荼。赛场上,业余评论员墨老师正在给观众做激情解说:“鬣狗群……咬住!咬住!鬣狗头子立功了!不要给斑马任何的机会!伟大的鬣狗!伟大的鬣狗头子!它继承了猛兽光荣的历史和传统!豹子、老虎、雄狮在这一刻灵魂附体!”

呃,这个,我们不要管那些场上选手的绰号了,现在的问题是有某个项目的n个选手进行循环比赛,其中n=2m,要求每名选手要与其他n-1名选手都赛一次。每名选手每天比赛一次,循环赛共进行n-1天,要求每天没有选手轮空。比赛时间表格如图所示(假定m=3)。

输入格式

输入为一个整数m,m≤5。

输出格式

输出为n行n列的整型矩阵,即比赛表格。每个元素之间由空格隔开,行末无多余空格。(注意:无需文件输入输出!)

样例

样例输入

复制2

样例输出

复制1 2 3 4
2 1 4 3
3 4 1 2
4 3 2 1

解析:

PS:可能是数据太小,C2024XSChejunling打表过了!

一个小例子:m = 2:

来观察一下:1.会发现左上与右下,右上与左下的数据是相同的。

2.左上与左下的第x个元素,永远相差m。

那么,我们可以这样分:

//x、y表示正方形的第一个点的坐标,边长为len,第一个元素的值为z
solve(x, y, len - 1, z);///左上
solve(x + t, y + t, len - 1, z);//右下
solve(x + t, y, len - 1, z + t);//左下
solve(x, y + t, len - 1, z + t);//右上

那么,如何求解呢?

很显然,当正方形中只包含一个元素时,直接求解。

if (len == 0) {a[x][y] = z;return ;
}

合并:因为求解时是将答案存在数组中,就相当于直接合并成了一个数组。

完整代码:

#include <bits/stdc++.h>
using namespace std;
int n, a[40][40];
void solve(int x, int y, int len, int z) {int t = pow(2, len - 1);if (len == 0) {a[x][y] = z;return ;}solve(x, y, len - 1, z);solve(x + t, y + t, len - 1, z);solve(x + t, y, len - 1, z + t);solve(x, y + t, len - 1, z + t);
}
int main() {cin >> n;int m = pow(2, n);solve(1, 1, n, 1);for (int i = 1;i <= m;i++) {for (int j = 1;j <= m;j++) {printf("%d%c", a[i][j], (j != m || i == m) ? ' ' : '\n');}}return 0;
}

分治中的快速排序:

算法说明:

简介:先从数据序列中选一个元素,并将序列中所有比该元素小的元素都放到它的右边或左边,再对左右两边分别用同样的方法处之,直到每一个待处理的序列的长度为1, 处理结束。

图片及文字举例:

定义双指针,i = 1,j = n。

选定基准数,6。

当i找到一个比基准数6大的数字,停止。

当j找到一个比基准数6小的数字,停止。

交换。

再次寻找。

交换。

i、j重合时,循环结束。

将基准数与当前数交换,使得基准数前面的数字比基准数小,后面的数比基准数大。(基准数归位)

注意,指针j先动。

why?

例如:6 1 2 7 9这组数据,i、j就走过头了。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5;
int n, a[N];
void qsort(int l, int r) {if (l >= r) return;int i = l, j = r, mid = a[i];while (i != j) {while (mid < a[j] && i < j) {j--;}while (mid >= a[i] && i < j) {i++;}swap(a[i], a[j]);}swap(a[l], a[i]);qsort(l, i - 1);qsort(i + 1, r);
}
int main() {scanf("%d", &n);for (int i = 1; i <= n; i++) {scanf("%d", &a[i]);}qsort(1, n);for (int i = 1; i <= n; i++) {printf("%d ", a[i]);}return 0;
}

分治中的归并排序:

归并与快排的区别:

归并:如上图,是真正的分治算法。

快排:只是分解了,没有真正意义上的分。

代码:

#include<iostream>
int n, s1[1000005], s2[1000005];
void merge(int L, int R, int Mid){int i = L;int j = Mid + 1;int k = L;while(i <= Mid && j <= R){if(s1[i] <= s1[j])s2[k ++] = s1[i ++];else{s2[k ++] = s1[j ++]; }}while(i <= Mid)s2[k ++] = s1[i ++];while(j <= R)s2[k ++] = s1[j ++];for(i = L; i <= R; i ++)s1[i] = s2[i];
}
void mergesort(int L, int R){if(L < R){int Mid = (L + R) / 2;mergesort(L, Mid),mergesort(Mid + 1, R);merge(L, R, Mid);}
}
int main(){scanf("%d", &n);for(int i = 1; i <= n; i ++)scanf("%d", &s1[i]);mergesort(1, n);for (int i = 1;i <= n;i++) printf("%d ", s1[i]);
}

PS:有merge这个函数,可以参考这篇博客:C++ merge函数_DannyCHIU的专栏-CSDN博客

小结:

摸底考试 + 分治算法中的原理及排序。

CSP:重庆八中宏帆初级中学校初一编程社C2024HF700寒假集训总结——Day1相关推荐

  1. 大家注意了,襄阳宏帆商务咨询有限公司是诈骗公司。

    襄阳宏帆商务咨询有限公司 188-2755-9894 各位注意了,此号码是骗子!是襄阳宏帆商务咨询有限公司 地址是湖北省襄阳市樊城区大庆东路人民广场奔泰阳光诚14楼1410室.请大家注意了,谨防受骗. ...

  2. 抛物线怎么用c语言编程,巧用宏程序对抛物线曲面编程

    原标题:巧用宏程序对抛物线曲面编程 对数控车床的零件进行编程,是我们完成自动加工的前提.在编程技术日益发展的今天,宏程序的运用,变量的设定,是对复杂零件编程不可或缺的重要工具. 经常有复杂曲线所构成的 ...

  3. 华科计算机学院三好学生,哲学学院常若帆荣获校“三好学生标兵”称号

    常若帆:"石可破也,而不可夺坚:丹可磨也,而不可夺赤.汗水与泪水,终将浇灌出绚丽的花朵.从当下开始,有所作为,才能遇见更好的自己." 2020年11月12日晚,"三好学生 ...

  4. linux 宏的作用域,Linux 系统编程:几个宏定义

    __init宏使内建模块中的init函数在执行完成后释放掉,仅用于初始化.编译器将所有代码存储到特殊的内存段中,初始化结束就释放这段内存. __initdata,和__init的作用基本上一样,不过它 ...

  5. lisp绘制法兰,[原创] Lisp 也玩宏录制 - AutoLISP/Visual LISP 编程技术 - CAD论坛 - 明经CAD社区 - Powered by Discuz!...

    fsxm发表于2009-5-6 20:13:00再将坐标精度加大一点...搞个entmake版的!平时有可能用的到-- ;此Lisp程序由nonsmall制作的宏记录器自动生成 (defun c:te ...

  6. 石油采集(求联通区域) 2018多校寒假集训 (dfs+二分匹配)

    题目: 链接:https://www.nowcoder.com/acm/contest/76/A 来源:牛客网 随着海上运输石油泄漏的问题,一个新的有利可图的行业正在诞生,那就是撇油行业.如今,在墨西 ...

  7. 关于『 一月の集训 』

    关于『 一月の集训 』 A B O U T J A N U A R Y \tt A \ B \ O \ U \ T \quad J \ A\ N\ U\ A\ R \ Y A B O U TJ A N ...

  8. 合肥八中2021年高考成绩查询,合肥八中2018高考喜报

    2019-1-24 14:09 编辑 虽然往年八中高考可能在...潜力很大,有望直追老二老大.很看好八中今后的发展 2019-01-24 14:05 最关注的各校喜报开始公布,搜集汇总在这里,给大家. ...

  9. 2021重庆江北中学高考成绩查询,2020年重庆部分中学高考成绩单,看看有你的母校吗?...

    文科重本线共有11117人,600分以上1835人.文科655分以上,全市共计57人 理科重本线共有42071人,600分以上7924人.理科700分以上的,全市共计54人 全国二卷理科状元:重庆八中 ...

最新文章

  1. 如何在ToolBar中显示文字和图标,自定义图标大小,并和MenuItem关联
  2. SQL Server的数据库开发工具
  3. JS进阶篇--ckplayer.js视频播放插件
  4. fatal error C1002: 在第2遍中编译器的堆空间不足
  5. 同时买票是怎么实现的_刷脸进站,语音买票!广州地铁这波操作666~
  6. 用重构指导Clean Code(二):依恋情结和switch语句
  7. python web后端和vue哪个难_全栈开发用纯后端模板与Vue+后端框架组合哪个好?
  8. 实现textbox输入时模糊查询
  9. AI 如何应用于油气勘探?
  10. 同步、异步的使用场景及好处
  11. Insus NET Utility
  12. C语言复习一(内存对齐、大小端)
  13. 20190904每日一句
  14. Struts框架可以支持以下哪种程序开发语言?(选择1项)
  15. 蓝桥杯 C语言 试题 历届试题 网络寻路
  16. 已解决:关于navicat premium数据库激活一直不成功的解决方法
  17. 2018第九届蓝桥杯C++省赛B组题目汇总
  18. 《Adobe Illustrator CS6中文版经典教程(彩色版)》—第0课0.4节应用颜色
  19. 无产权证的房产能让渡吗?
  20. 「米聊」突然复活,雷布斯真的是出其不意

热门文章

  1. 计算机策略更新失败用户策略更新失败,升级更新win10遇到错误代码8024000B的两种解决办法...
  2. 学习笔记-Windows 安全
  3. Chains (链 )
  4. 日本最大移动互联网公司Gree的秘密
  5. Vue进阶(三十六):created() 详解
  6. Python3 queue队列类
  7. sql触发器Tigger
  8. 金山办公2020校招前端开发工程师笔试题
  9. 一个很棒的字帖生成器
  10. pr-流程、界面、操作流程1