目录
第0套题详解(SUM Problem 、 A+B problem)
ACM实训课程考核
考核内容
项目参照ACM-ICPC竞赛的评价规则进行考核,即学生在指定地点和规定时间内完成给出的程序设计题目,并按照最终通过的题目数量及时间进行等级评分。
备赛安排
1)预备阶段 了解ACM程序设计竞赛的基本流程,掌握并参与ACM程序设计竞赛的基本步骤。(VJudge) 第11周完成。
2)练习阶段 总结相关算法知识,并进一步学习及强化。(自习)
练习一定数量的ACM程序设计竞赛题目。(VJudge)
每周1次练习赛(周日晚7:00-9:00)。(VJudge) 第11-14周完成。
3)考核阶段 现场比赛(STU OJ) 第15周完成。
推荐学习资源
视频资源1: 蓝桥杯ACM算法竞赛辅导 https://www.bilibili.com/video/BV174411D7SK
视频资源2 算法讲堂(电子科技大学) https://space.bilibili.com/7711573/channel/seriesdetail?sid=1071937
ACM实训准备规划
前话
本人对算法一窍不通,虽苦苦挣扎3年,但还是始终处于小白的感觉,故本系列仅为我顺利通过ACM实训课程备考和复习服务,仅供大家参考即可
历届习题(未曾改变)
第0套
第1套
第2套
Anton and Danik、人见人爱A^B、Tokitsukaze and All Zero Sequence、Aggressive cows、Brainman、Tokitsukaze and Good 01-String (hard version)
第3套
统计元音、Let the Balloon Rise、Election Time、0-1 Knapsack Problem、Drying、N皇后问题
第4套
Digit Counting、Add All、Oil Deposits、Dungeon Master、Is It A Tree?、Global Raining at Bididibus
规划
5.8 - 5.12 (11周)
- 掌握第0套和第1套的习题
- 在5.12之前熟练理解并会编写上述习题,理清思路
- 看ACM社团录制视频基础部分,进行回顾
- 完成蓝桥杯ACM算法竞赛辅导1-2讲视频,将其java转为c语言
- 进行必要的算法练习,举一反三
5.13-5.19(12周)
- 复习第0套和第1套的习题,以及上周所掌握的知识
- 掌握第2套的习题
- 在5.19之前熟练理解并会编写上述习题,理清思路
- 看ACM社团录制视频基础部分,进行回顾
- 完成蓝桥杯ACM算法竞赛辅导3-5讲视频,将其java转为c语言
- 进行必要的算法练习,举一反三
5.20-5.26(13周)
- 复习第1套和第2套的习题,以及上周所掌握的知识
- 掌握第3套的习题
- 在5.26之前熟练理解并会编写上述习题,理清思路
- 看ACM社团录制视频基础部分,进行回顾
- 完成蓝桥杯ACM算法竞赛辅导6-7讲视频,将其java转为c语言
- 进行必要的算法练习,举一反三
5.27-6.2(14周)
- 进入复习阶段,对前3周所学内容进行差缺补漏
- 掌握第4套的习题
- 在6.2之前熟练理解并会编写上述习题,理清思路
- 看ACM社团录制视频基础部分,进行回顾
- 观看算法讲堂
- 进行必要的算法练习,举一反三
5.8 学习
【碎碎念】今天学习任务量较为轻松,明天可能会需要开始做项目,故今天学习多一些。。。
基础回顾:基本语法
1.输入输出
#include<stdio.h>
int main(){
// 将数字字符转为数字
char c;
scanf("%c",&c);
scanf("%d",c-'0');
return 0;
}
- 所有变量都要先声明再使用,声明的时候注意命名规范
- main函数忘记加返回值
- 记得加分号
- 区分中英文标点
2.基本运算
++a 相当于 a=a+1
逻辑运算符(用在条件上面)
类型转换
#include <stdio.h>
int main( ){
//数字反转
char a,b,c,d;
scanf("%c%c%c.%c",&a,&b,&c,&d);
printf("%c.%c%c%c",d,c,b,a);
return 0;
}
3.循环语句
#include<stdio.h>
int main(){
//循环 一尺之锤
int a, day=1;
scanf("%d",&a);
while(a>1){
a = a/2;
day = day +1;//天数加一
}
printf("%d",day);
return 0;
}
#include<stdio.h>
int main(){
//寻找最小值
int n , min =1000;
scanf("%d",&n);
for(int i=1 ; i<=n ; i++){
int tmp;
scanf("%d",&tmp);
if(tmp < min) min = tmp ;
}
printf("%d",min);
return 0 ;
}
4. 分支和条件
闰年的判断
#include<stdio.h>
int main(){
int year;
//输入year
scanf("%d",&year);
//判断能否被4整除
if (year % 4 == 0){
//判断能否被400整除
if (year % 100 != 0 ){
printf("1");
}
else if(year % 400 == 0 ){
printf("1");
}else{
printf("0");
}
}else{
printf("0");
}
return 0;
}
5.函数
#include<stdio.h>
//函数事先要声明
int add(int a,int b)
int main(){
int m = 2, n = 7;
int res = add(m,n);
return 0;
}
int add(int a, int b){
return a+b;
}
6.数组
第0套题详解(SUM Problem 、 A+B problem)
SUM Problem
问题
在这个问题中,你的任务是计算SUM(n) = 1 + 2 + 3 +…+ n。
输入
输入将由一系列整数n组成,每行一个整数。
输出
对于每种情况,在一行中输出SUM(n),后面跟着一个空行。您可以假设结果将在32位有符号整数的范围内。
思路
每输入一个数,输出当前已经输入的所有数据的和。需要注意判断是否读到结尾
代码
#include<stdio.h>
int main(){
//声明变量
int n,sum;
//循环输入
while(scanf("%d",&n)!=EOF){
if(n%2==0)
sum=n/2*(n+1);
else
sum=(n+1)/2*n;
printf("%d\n\n",sum);
}
return 0;
}
# include<stdio.h>
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int sum=0;
for(int i=0;i<=n;i++)
{
sum+=i;
}
printf("%d\n\n",sum);
}
return 0;
}
A+B problem
问题
我有个很简单的问题要问你。给定两个整数A和B,你的任务是计算A + B的和。
输入
输入的第一行包含一个整数T(1<=T<=20),它表示测试用例的数量。然后是T行,每行由两个正整数A和b组成。注意,整数非常大,这意味着您不应该使用32位整数来处理它们。您可以假设每个整数的长度不超过1000。
输出
对于每个测试用例,您应该输出两行。第一行是“Case #:”,#表示测试用例的编号。第二行是等式“A + B = Sum”,Sum表示A + B的结果。注意,在等式中有一些空格。输出两个测试用例之间的空行。
思路
读取多组输入的大整数(字符串形式),将它们相加,并以大整数的形式输出结果。
-
读取测试用例数量:首先读入一个整数
T
,表示接下来有T组大整数相加的测试用例。 -
循环处理每组测试用例:通过一个for循环,迭代处理T组输入。
-
读取大整数:对于每组测试,分别读入两个大整数
number1
和number2
,存储为字符数组。 -
初始化和计算:
- 初始化一个数组
sum
用于存放两数相加的结果及其进位,长度足够大且预先全部置零。 - 从最低位(个位)开始,对齐或补零后逐位相加,同时处理进位。这里利用了字符串的逆序遍历,即从末尾向前遍历。
- 如果当前位的和大于等于10,则产生进位,将该位的值变为余数,并在更高位累加进位的商。
- 初始化一个数组
-
输出结果:
- 按照指定格式输出每组测试用例的输入大整数和它们的和。
- 注意最高位可能产生的额外进位。
代码
#include <stdio.h>
#include <string.h>
int main(){
int T;
scanf("%d", &T);
int j,k;
for (j = 1; j <= T; j++){
char number1[1000];
char number2[1000];
int sum[1000] = {0};//置0
//memset(sum, 0, sizeof(int));//int 类型怎么置0
scanf("%s%s", number1, number2);
int len1 = strlen(number1);
int len2 = strlen(number2);
int i;
for (i = 0; i < len1 || i < len2; i++){
if (i < len1)
sum[i] += number1[len1 - i - 1] - '0';//字符转换为数字
if (i < len2)
sum[i] += number2[len2 - i - 1] - '0';
if (sum[i] >= 10)
{
sum[i + 1] = sum[i] / 10;
sum[i] = sum[i] % 10;
}
}
printf("Case %d:\n", j);//格式输出
for (k = 0; k<len1; k++)
printf("%c", number1[k]);
printf(" ");
printf("+");
printf(" ");
for (k = 0; k<len2; k++)
printf("%c", number2[k]);
printf(" ");
printf("=");
printf(" ");
if (len1 < len2)//判断谁最长
len1 = len2;
if (sum[i]>0)
printf("%d", sum[i]);//最高位产生进位
for (i = len1 - 1; i >= 0; i--)
printf("%d", sum[i]);
printf("\n\n");
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 1005
int main()
{
int t,i,j,k,count=1;//count用来记实例序号
char a[MAX],b[MAX];
int na[MAX],nb[MAX];//数字数组
int sum[MAX],pre;//pre表示前一位
scanf("%d",&t);
while(t--){
memset(sum,0,sizeof(sum));
memset(na,0,sizeof(na));
memset(nb,0,sizeof(nb));
scanf("%s%s",a,b);
pre=0;
int lena = strlen(a);
int lenb = strlen(b);
//字符串反转且字符串变数字
for(i=0;i<lena;i++)
na[lena-1-i] = a[i]-'0';
for(j=0;j<lenb;j++)
nb[lenb-1-j] = b[j]-'0';
int lenx=lena>lenb?lena:lenb;
//逐位相加(从最低位开始加)
for(k=0;k<lenx;k++){
sum[k]=na[k]+nb[k]+pre/10;
pre=sum[k];
}
while(pre>9){
sum[lenx]=pre/10%10;//最高位有了进位了
lenx++;
pre/=10;
}
printf("Case %d:\n",count++);
printf("%s + %s = ",a,b);
for(i=lenx-1;i>=0;i--){
printf("%d",sum[i]%10);//输出每一位 每一位是sum数组中的每一项对10取余
}
printf("\n");
if(t)
printf("\n");
}
return 0;
}
明天学习计划:复习今天所学内容和代码,学习蓝桥杯ACM算法竞赛辅导第一讲