第一题:旗鼓相当的对手
题目描述
有N个同学,每个同学三科成绩(每门分数<=150),如果两名同学<i,j>的总分不超过10分且单科分差不超过5分,则两个同学是旗鼓相当的对手,求总对数。
样例测试
AC代码
#include<bits/stdc++.h>
using namespace std;
int main(){
int N; //参加的同学人数
cin>>N;
int a[N][3];
int sum=0; //旗鼓相当的对手个数
int sum1,sum2; //两个同学各自的总分
for(int i=0;i<N;i++){ //录入成绩
cin>>a[i][0]>>a[i][1]>>a[i][2];
}
for(int i=0;i<N-1;i++){
sum1 = a[i][0]+a[i][1]+a[i][2];
for(int j=i+1;j<N;j++){
sum2 = a[j][0]+a[j][1]+a[j][2];
if(abs(sum1-sum2)>10){ //判断总成绩分差
continue;
}else{ //判断单科分差
if(abs(a[i][0]-a[j][0])<=5 && abs(a[i][1]-a[j][1])<=5 && abs(a[i][2]-a[j][2])<=5){
sum++;
}
}
}
}
cout<<sum; //输出总个数
return 0;
}
易错点
计算分差带绝对值abs()
切记数组下标从0开始
第二题:工艺品制作
题目描述
有一个长宽高分别为w,x,h的实心玻璃立方体,由1*1*1的方块组成,每个方块坐标(i,j,k)。现对该方块进行q次切割,切割出立方体空洞,每次切割的对角坐标为(x1,y1,z1)和(x2,y2,z2)且保证1<=w<=20,1<=q<=100,1<=x1<=x2<=w,1<=y1<=y2<=x,1<=z1<=z2<=h。求切割完成后剩余的小方块个数sum。
样例测试
AC代码
#include<bits/stdc++.h>
using namespace std;
int a[21][21][21]; //定义在函数外部的数组默认赋0
int main(){
int sum=0; //剩余方块个数
int w,x,h; //长,宽,高
int q; //切割次数
int x1,y1,z1,x2,y2,z2; //两个切割点
cin>>w>>x>>h;
cin>>q;
while(q--){
cin>>x1>>y1>>z1>>x2>>y2>>z2;
for(int i=x1;i<=x2;i++){
for(int j=y1;j<=y2;j++){
for(int k=z1;k<=z2;k++){
a[i][j][k] = 1;
}
}
}
}
for(int i=1;i<=w;i++){
for(int j=1;j<=x;j++){
for(int k=1;k<=h;k++){
if(a[i][j][k] == 0){
sum++;
}
}
}
}
cout<<sum;
return 0;
}
易错点
整型数组定义在main函数外部时,默认值为0
第三题:彩票摇奖
题目描述
现有一项彩票活动,规则如下:
-
每张彩票上印有 7 个各不相同的号码,且这些号码的取值范围为1~33
-
每次在兑奖前都会公布一个由7个各不相同的号码构成的中奖号码
-
设置特等奖和一到六等奖共7个奖项,对应猜中号码个数7~1,不考虑号码位置
依次输入小明购买的彩票个数、中奖号码以及小明购买的所有彩票号码,统计其各个奖项的中奖次数,从特等到六等排序。
样例测试
AC代码
#include<bits/stdc++.h>
using namespace std;
int price[7];
int main(){
int num,s; //彩票张数,相同号码个数
int a[7]; //中奖号码串
int temp; //每次输入购买号码
cin>>num; //输入数据
for(int i=0;i<7;i++){
cin>>a[i];
}
while(num--){
s = 0; //初始化相同个数为0
for(int i=0;i<7;i++){
cin>>temp;
for(int i=0;i<7;i++){
if(temp==a[i]){
s++;
break;
}
}
}
if(s>0){
price[7-s]++; //对应奖项(特等~六等)
}
}
for(int i=0;i<7;i++){ //输出结果
cout<<price[i]<<' ';
}
return 0;
}
第四题:神奇的幻方
题目描述
幻方是一种很神奇的N*N 矩阵:它由数字1,2,3,⋯⋯,N*N 构成,且每行、每列及两条对角线上的数字之和都相同,构建方法如下:
现给定N,请按照上述方法构造N*N幻方。
样例测试
AC代码
#include<bits/stdc++.h>
using namespace std;
int price[7];
int main(){
int N; //幻方的边长(奇数)
cin>>N;
int num=N*N;
int K=1; //初始值
int a[N][N]; //定义幻方矩阵
memset(a,0,sizeof(a)); //初始化为0
a[0][N/2] = 1; //第一行中间为 1
int row,column; //上一个幻方的行、列
row = 0;
column = N/2;
while(K<num){
K++;
if(row==0 && column!=N-1){ //1、第一行但不是最后一列
row = N-1;
column++;
a[row][column] = K;
continue;
}
if(row!=0 && column==N-1){ //2、第一列但不是最后一行
row--;
column = 0;
a[row][column] = K;
continue;
}
if(row==0 && column==N-1){ //3、右上角
row++;
a[row][column] = K;
continue;
}
if(row!=0 && column!=N-1){ //4、不是第一行也不是最后一列
if(a[row-1][column+1]==0){
row--;
column++;
a[row][column] = K;
continue;
}else{
row++;
a[row][column] = K;
continue;
}
}
}
for(int i=0;i<N;i++){ //输出幻方
for(int j=0;j<N;j++){
cout<<a[i][j]<<' ';
}
cout<<endl;
}
return 0;
}
易错点
定义静态数组时要用常量,若用不确定的变量N初始化数组长度,则可以用memset初始化数组的值。
第五题:珠心算测验
题目描述
某学校的珠心算老师采用一种快速考察珠心算加法能力的测验方法。他随机生成一个正整数集合,集合中的数各不相同,然后要求学生回答:其中有多少个数,恰好等于集合中另外两个(不同的)数之和?
样例测试
AC代码
#include<bits/stdc++.h>
using namespace std;
int main(){
int num,tag; //数字总数,该数字是否已进入数组
int sum=0; //两数之和符合条件的对数
cin>>num;
int a[num]; //创建数组存储数字
for(int i=0;i<num;i++){
cin>>a[i];
}
sort(a,a+num); //排序后不用枚举比自己大的数,降低时间复杂度
for(int i=2;i<num;i++){ //枚举第3位和以后的数
tag = 1; //刷新数字状态
for(int j=0;j<i-1;j++){ //首位数字到枚举数字的前两位为止
for(int k=j+1;k<i;k++){ //次位数字到枚举数字的前一位为止
if(tag && a[j]+a[k]==a[i]){
sum++;
tag = 0;
}
}
}
}
cout<<sum;
return 0;
}
易错点
本题要寻找的是符合条件的数字的个数,而不是符合条件的算式个数,所以要使用一个标记tag,当某个数字第一次符合要求时总数+1,后续若该数字仍满足则总数不加。
第六题:爱与愁的心痛
题目描述
最近有n个不爽的事,每件事都有一个正整数刺痛值(心理承受力极差)。爱与愁大神想知道连续m个刺痛值的和的最小值是多少,但是由于业务繁忙,爱与愁大神只好请你编个程序告诉他。
样例测试
AC代码
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m; //n件事;求连续m件事的最小刺痛值
int temp,sum; //临时最小值;每次连续m刺痛值的和
cin>>n>>m;
int a[n];
for(int i=0;i<n;i++){ //存储到数组
cin>>a[i];
}
for(int i=0;i<=n-m;i++){
sum = 0;
for(int j=i;j<i+m;j++){
sum += a[j];
}
if(i==0){ //第一次计算sum值直接赋值给temp
temp = sum;
}else{ //后续赋最小值
temp = min(temp,sum);
}
}
cout<<temp;
return 0;
}
易错点
确定m宽的滑窗初始地址时,要保证能取到a[n-m],即i<=n-m。
第七题:插火把
题目描述
在游戏《我的世界》里选定n*n的空地,分别放置火把和萤石,可以照亮周围的一些区域,范围如下:
火把:|暗|暗| 光 |暗|暗| 萤石:|光|光| 光 |光|光|
|暗|光| 光 |光|暗| |光|光| 光 |光|光|
|光|光|火把|光|光| |光|光|萤石|光|光|
|暗|光| 光 |光|暗| |光|光| 光 |光|光|
|暗|暗| 光 |暗|暗| |光|光| 光 |光|光|
分别输入n(边长),m(火把数),k(萤石数)
第2~m+1行输入火把坐标,继而输入萤石坐标
最后输入可以生成怪物的格子数
样例测试
AC代码
#include<bits/stdc++.h>
using namespace std;
int T[110][110]; //最大的面积
int main(){
int n,m,k; //列数,火把数,萤石数
int x,y; //火把 萤石的坐标
int sum=0; //可以生成怪物的格子总数
cin>>n>>m>>k;
for(int i=1;i<=m;i++){ //火把照亮
cin>>x>>y;
x += 2; //防止越界产生RE
y += 2;
for(int j=-2;j<=2;j++){
T[x+j][y] = 1;
T[x][y+j] = 1;
}
T[x-1][y-1]=T[x+1][y-1] = 1; //补充四个角
T[x-1][y+1]=T[x+1][y+1] = 1;
}
for(int i=1;i<=k;i++){ //萤石照亮
cin>>x>>y;
x += 2;
y += 2;
for(int j=0;j<=2;j++){
for(int h=0;h<=2;h++){
T[x+j][y+h] = 1;
T[x+j][y-h] = 1;
T[x-j][y+h] = 1;
T[x-j][y-h] = 1;
}
}
}
for(int i=3;i<=n+2;i++){
for(int j=3;j<=n+2;j++){
if(T[i][j]==0){
sum++;
}
}
}
cout<<sum;
return 0;
}
易错点
对数组越界部分赋值会造成超时RE