第一题
编程实现:求和
题目描述:
有一组1到100000的正整数数据,当给定一个正整数N(1<N<100000),求出其左右相邻的两个正整数的和。
例如:N = 6,6左边相邻的正整数为5,6右边相邻的正整数为7,两个正整数的和为12(12=5+7)。
输入描述
输入一个正整数N(1<N<100000)
输出描述
输出一个正整数,表示N左右相邻的两个正整数的和
样例输入
6
样例输出
12
#include<iostream>
using namespace std;
int main(){
int N;
cin>>N;
cout<<(N-1)+(N+1);
//cout<<2*N;//同样效果
return 0;
}
题目解析:
题目的要求就是实现输入一个正整数N,
然后输出N-1和N+1的和,也就是N的2倍(2*N)
数据规模不算大,
正整数以及1<N<100000的数据范围
也提示避开了1和0这类特殊边界数值。
所以通过整数类型直接求出N-1和N+1的和即可。
输入输出格式上没有特殊需求。
第二题:
编程实现:数字判断
题目描述:
给定两个正整数N和M(10≤N<M≤10000),请计算出N到M之间(包含N和M)的所有正整数中,各位上的数字都为奇数的正整数有多少个。
例如:N = 110,M = 119,
110到119之间的所有正整数有110、111、112、113、114、115、116、117、118、119;
其中各位上的数字都为奇数的正整数有111、113、115、117、119,共5个。
输入描述
输入两个正整数N和M(10≤N<M≤10000),正整数之间以一个空格隔开
输出描述
输出一个整数,表示N到M之间(包含N和M)的所有正整数中,各位上的数字都为奇数的正整数的个数
样例输入
110 119
样例输出
5
#include<cstdio>
using namespace std;
int main(){
int N,M,cnt = 0;//cnt用于统计符合条件的数的个数
scanf("%d %d",&N,&M);
for(int i=N;i<=M;i++){
int j = i;//利用临时变量j来分解数位
int tmp = 0;//tmp记录数位出现偶数的次数
/*======拆分数位判断过程======*/
while(j){//拆数位
int k = j%10;//取出个位
if(k%2==0){//一旦发现该数位是偶数
tmp++;//tmp更新
break;//跳出循环,没必要再判断下一个数位了
}
j/=10;//每次将个位去掉
}
if(tmp==0){//如果tmp还是0,说明每个数位都是奇数
cnt++;
}
/*======拆分数位判断过程======*/
}
printf("%d",cnt);
return 0;
}
题目解析:
题目的要求就是在正整数N与M之间的任意数之中,
如果这个数的各数位都是奇数,就统计入计数。
这里需要注意的是数据的范围,10≤N<M≤10000。
因此每个数的数位长度不一定相同,必须采用循环来分解数位。
在判断思路上,依次看每个数位是否为奇数,
都满足则加入统计,这是一种方式;
另一种方式是立一个临时变量初始值为0,
碰到一个数位是偶数,就修改临时变量,
如果最后临时变量为零,说明所有数位都是奇数。
第三题:
编程实现:扑克牌
题目描述:
有N(3≤N≤50)张反面朝上的扑克牌排成一排,每次可以翻转任意3张扑克牌(正面翻转后为反面,反面翻转后为正面,且不考虑正面花色和点数),请问最少翻转几次可以将N张扑克牌全部翻转为正面。
例如:
N=5,最少翻转3次可以使5张扑克牌全部翻转为正面朝上。
输入描述
输入一个正整数N(3≤N≤50),表示扑克牌的数量
输出描述
输出一个整数,如果可以将N张反面朝上的扑克牌全部翻转为正面朝上,输出最少需要翻转的次数,否则输出-1
样例输入
5
样例输出
3
#include<iostream>
using namespace std;
int main() {
int N;
cin>>N;
if(N==4) {
cout<<4<<endl;
} else {
cout<<N/3+N%3<<endl;
}
return 0;
}
题目解析:
有N(3≤N≤50)张反面朝上的扑克牌。
每次翻转任意3张,
最少翻转几次可以将N张扑克牌全部翻转为正面。
如果模拟几个情况,就会发现其中规律:
(以下用1表示反面,0表示正面)
当N=4时,翻4次;
1 1 1 1
0 0 0 1
0 1 1 0
1 0 1 1
0 0 0 0
当N=5时,翻3次;
1 1 1 1 1
0 0 0 1 1
0 1 1 0 1
0 0 0 0 0
当N=6时,翻2次;
1 1 1 1 1 1
0 0 0 1 1 1
0 0 0 0 0 0
当N=7时,翻3次;
1 1 1 1 1 1 1
0 0 0 1 1 1 1
0 0 1 0 0 1 1
0 0 0 0 0 0 0
当N=8时,翻4次;
1 1 1 1 1 1 1 1
0 0 0 1 1 1 1 1
0 0 0 0 0 0 1 1
0 0 0 0 1 1 0 1
0 0 0 0 0 0 0 0
当N=9时,翻3次;
1 1 1 1 1 1 1 1 1
0 0 0 1 1 1 1 1 1
0 0 0 0 0 0 1 1 1
0 0 0 0 0 0 0 0 0
当N=10时,翻4次;
1111111111
0001111111
0000001111
0000010011
0000000000
当N=11时,翻5次;
11111111111
00011111111
00000011111
00000000011
00000001101
00000000000
这时候会发现当这个数是3的倍数(能被3整除),倍数就是翻转的次数。//余数为0时
要注意4这个特殊的边界存在,其余的数都符合以下规则:
当这个数除3余1或余2时,请注意看样例,是不是最后的步骤都一样,
最后步骤的执行次数,恰好是除3的余数。
而相同步骤之前翻转的次数,恰好是除3的商。
再仔细看看发现翻转次数正好是除3的余数与商之和。
第四题:
编程实现:最大空白区
题目描述:
小明有一张N*M的方格纸,且部分小方格中涂了颜色,部分小方格还是空白。
给出N(2≤N≤30)和M(2≤M≤30)的值,及每个小方格的状态(被涂了颜色小方格用数字1表示,空白小方格用数字0表示),请帮助小明找出最大的矩形空白区域,并输出该矩形空白区域由多少个小方格组成。
例如:N=4,M=5,4*5的方格纸中每个小方格的状态如下图:
最大的空白区域由6个小方格组成(红色框区域)。
输入描述
第一行输入两个正整数N和M(2≤N≤30,2≤M≤30),分别表示方格纸的行数和列数,两个正整数之间以一个空格隔开
第二行开始输入N行,每行M个整数(整数为1或者0),1表示涂色方格,0表示空白方格,整数之间以一个空格隔开
输出描述
输出一个整数,表示最大矩形由多少个小方格组成(如果没有空白小方格,输出0)
样例输入
4 5
1 1 0 0 0
1 0 1 0 0
0 0 0 1 1
0 0 0 1 0
样例输出
6
#include<cstdio>
using namespace std;
int main(){
int N,M;
int max = 0;
scanf("%d %d",&N,&M);
int arr[N][M];
//输入过程
for(int i=0;i<N;i++){
for(int j=0;j<M;j++){
scanf("%d",&arr[i][j]);
}
}
//寻找最大矩形过程
for(int i=0;i<N;i++){
for(int j=0;j<M;j++){
int tmp = 0;
//每个点开始范围判断
for(int x=i;x>=0;x--){
for(int y=j;y>=0;y--){
int sum = 0;
for(int a=i;a>=x;a--){
for(int b=j;b>=y;b--){
sum += arr[a][b];
}
}
if(sum==0){
tmp = (i-x+1)*(j-y+1);
if(tmp>max) max = tmp;
}
}
}
}
}
printf("%d\n",max);
system("Pause");
return 0;
}
题目解析:
当遍历到每个元素时,以当前元素为起点,以行列0下标为边界逐层圈定范围。由于元素都是1和0,通过统计圈定范围的元素的总和,如果结果等于0,说明都是由0组成。再通过圈定范围的二维数组的行列下标计算出元素个数,如果是最多的更新最大空白区值。