目录
前言
一、选择题
1.题目描述
2.参考答案
二、编程题
1.比较大小
题目描述
题目解析
AC代码
#include<iostream>//调用输入输出流头文件
#include<algorithm>//调用算法头文件
using namespace std;//使用标准名字空间
int main(){//主函数开始
int m,n;//定义整数类型变量m,n
cin>>m>>n;//输入m,n的值
cout<<max(m,n);//输出m,n的最大值
return 0;//主函数结束,返回0
}
2.分成整数
题目描述
题目解析
AC代码1(模拟)
#include<iostream>//调用输入输出流头文件
using namespace std;//使用标准名字空间
bool n37(int n){//子函数,用来判断参数是否含有数字3或7
while(n){
if(n%10==3 or n%10==7) return 1;//如果个位为3或7,返回1
n/=10;//删除个位
}
return 0;//如果各位都没有3或7,返回0
}
int main(){//主函数开始
int n,cnt=0;//定义整数类型变量n,cnt并初始化赋值为0
cin>>n;//输入n的值
for(int i=1;i<=n/3-1;i++){//i为三数中最小,至多为n/3-1
if(n37(i)) continue;//如果i含有3或7,跳出本次循环,枚举下一个i
for(int j=i+1;j<=n/2;j++){//j为三数中第二小,至多为n/2,保证大于i
if(n37(j)) continue;//如果j含有3或7,跳出本次循环,枚举下一个j
if(n37(n-i-j)) continue;//如果n-i-j含有3或7,跳出本次循环,枚举下一个j
if(n-i-j>j) cnt++;//走到这一步,则三个正整数一定都不含3或7,只需保证n-i-j>j,则拆分符合条件
}
}
cout<<cnt;//输出cnt的值
return 0;//主函数结束,返回0
}
AC代码2(dfs)
#include<iostream>//调用输入输出流头文件
using namespace std;//使用标准名字空间
int cnt;//定义整数类型变量cnt
bool ex_37(int n){//判断37;
while(n){
if(n%10==3 || n%10==7) return 0;//若n包含3或7, 返回 0
n/=10;//查看下一位
}
return 1;//否则返回 1
}
void dfs(int n,int k,int a){//将 n拆成 k份, 至少拆 a
if(k==1){ //已拆完
if(n>=a) cnt+=ex_37(n);//能拆时,判断n是否含有37
return;//返回
}
for(int i=a;i*k<=n;i++) //继续拆
if(ex_37(i))//如果没有37
dfs(n-i,k-1,i+1);//递归
}
int main(){//主函数开始
int n;//定义整数类型变量
cin>>n;//输入n的值
dfs(n,3,1);//深搜
cout<<cnt<<endl;//输出cnt
return 0;//主函数结束,返回0
}
3.组合
题目描述
题目解析
AC代码1(数论)
#include<iostream>//调用输入输出流头文件
using namespace std;//使用标准名字空间
int main(){//主函数开始
int n,m;//定义整数类型变量n,m
cin>>n>>m;//输入n,m的值
int i=m*n-1;//i从m*n-1开始向下枚举
while(1){//装死循环
int j=i,flag=1;//用j代替i来枚举,因为过程中需要j不停自减,立个flag
while(j>=0){//当j还为正整数时,继续检查j
if(j%n==0) {flag=0;break;}//如果j是n的倍数,则一定能表示出来,flag倒下,跳出循环
j-=m;//如果j不是n的倍数,减掉一个m后继续检查
}
if(flag==1) break;//如果flag还在,说明j一直不能被表示,跳出循环
i--;//如果flag倒了,则说明j能被表示,i--,检查下一个数,继续循环
}
cout<<i;//输出i的值
return 0;
}
AC代码2(Sylvester定理)
#include<iostream>//调用输入输出流头文件
using namespace std;//使用标准名字空间
int main(){//主函数开始
int n,m;//定义整数类型变量n,m
cin>>n>>m;//输入n,m的值
cout<<n*m-n-m<<endl;//输出n*m-n-m的值并换行
return 0;//主函数结束,返回0
}
4.最大值
题目描述
题目解析
AC代码1(模拟)
#include<iostream>//调用输入输出流头文件
#include<algorithm>//调用算法头文件
using namespace std;//使用标准名字空间
int main(){//主函数开始
int n,k;int a[500],b[500]; //数组a,b分别用来存储长和宽
cin>>n;//输入n的值
for(int i=0;i<n;i++)//for循环,计数器i从0自增到n-1,共循环n次
cin>>a[i]>>b[i];//输入n个长方形的长和宽
cin>>k;//输入k的值
int big=max(*max_element(a,a+n),*max_element(b,b+n));//找到所有长宽中的最大值
while(1){//装死循环
int sum=0;//sum用来存储所有正方形中能剪出的正方形个数
for(int i=0;i<n;i++)
sum+=(a[i]/big)*(b[i]/big);//对于每一个要剪出的正方形,每张纸能剪出的个数即为该算式
if(sum>=k) break;//如果正方形个数够了,跳出循环
big--;//big自减1
}
cout<<big;//输出此时的边长
return 0;//主函数结束,返回0
}
AC代码2(二分查找)
#include<iostream>//调用输入输出流头文件
using namespace std;//使用标准名字空间
int n,k,w[509],h[509];//定义整数类型n,k,w[509],h[509]
bool check(int a){//判断: 切边长为 a的小正方形能否凑够 k个
int cnt=0;//定义计数器cnt
for(int i=0;i<n;++i)//for循环,计数器i从0自增到n-1,共循环n次
cnt+=(w[i]/a)*(h[i]/a); //就硬切, 然后硬加
return (cnt>=k); //返回cnt是否大于k
}
int main(){//主函数开始
cin>>n;//输入n的值
for(int i=0;i<n;++i)//for循环,计数器i从0自增到n-1,共循环n次
cin>>w[i]>>h[i];//w和 h的顺序其实也无所谓, 摊手
cin>>k;//输入k的值
int L=1, R=*max_element(w,w+n)+1;//随便搞个上下限, 无脑二分:
while(L+1<R){//当L+1小于R
int mid=(L+R)/2;//往中间猜
if(check(mid)) L=mid;//猜对-->边长小了-->提高下限
else R=mid;//猜错-->边长大了-->降低上限
}
cout<<L<<endl;//输出L的值
return 0;//主函数结束,返回0
}
5.农作物
题目描述
题目解析
AC代码
#include<iostream>//调用输入输出流头文件
using namespace std;//使用标准名字空间
char farm[509][509];//土地 farm: R代表农田, X代表杂草
int sign[509][509];//状态 sign: 0代表未知, 1代表已知农田, -1代表已知杂草
void dfs(int i,int j){//记录所有相邻的农田
if(sign[i][j]) return;//搜过了
if(farm[i][j]=='X')//如果有杂草
sign[i][j]=-1;//记住杂草
else{//否则
sign[i][j]=1;//记住农田, 看看周围有无农田
dfs(i-1,j);//上
dfs(i+1,j);//下
dfs(i,j-1);//左
dfs(i,j+1);//右
}
}
int main() {//主函数结束,返回0
int n,m,cnt;//定义整数类型变量n,m,cnt
cin>>n>>m;//输入n,m的值
for(int i=1;i<=n;++i)//for循环,计数器i从1自增到n,共循环n次
for(int j=1;j<=m;++j)//for循环,计数器j从1自增到m,共循环m次
cin>>farm[i][j];//缓冲带: 用杂草把农田围起来
for(int i=0;i<=n+1;++i)//for循环,计数器i从0自增到n+1,共循环n+2次
sign[i][0]=sign[i][m+1]=-1;//记录
for(int j=0;j<=m+1;++j)//for循环,计数器j从0自增到m+1,共循环m+2次
sign[0][j]=sign[n+1][j]=-1;//记录
//开搜
for(int i=1;i<=n;++i)//for循环,计数器i从1自增到n,共循环n次
for(int j=1;j<=m;++j)//for循环,计数器j从1自增到m,共循环m次
if(!sign[i][j] && farm[i][j]=='R'){//发现了未被记录过的农田
cnt++;//cnt自增1
dfs(i,j);//以此为起点开始搜索
}
cout<<cnt<<endl;//输出cnt的值
return 0;//主函数结束,返回0
}
6.面积
题目描述
题目解析
AC代码1
#include<iostream>//调用输入输出流头文件
using namespace std;//使用标准名字空间
bool xy[110][110];//二维数组,用来组成点阵信息
int ans;//定义整数类型变量ans
int main(){//主函数开始
int n;//定义整数类型变量
cin>>n;//输入n的值
int x1,y1,x2,y2;//定义整数类型变量x1,x2,y1,y2
for(int i=0;i<n;i++){
cin>>x1>>y1>>x2>>y2;//循环输入每一个矩形的坐标信息
for(int j=y1+1;j<=y2;j++)
for(int k=x1+1;k<=x2;k++)
xy[j][k]=1;//记录每个矩形点阵信息
}
for(int j=1;j<=109;j++){//for循环,计数器i从1自增到109,共循环109次
for(int k=1;k<=109;k++)//for循环,计数器k从1自增到109,共循环109次
if(xy[j][k]) ans++;//累积数组中为真的个数,即为面积
}
cout<<ans;//输出ans
return 0;//主函数结束,返回0
}
AC代码2
#include<iostream>//调用输入输出流头文件
using namespace std;//使用标准名字空间
int a[509][509],n;
int main(){//主函数开始
int x1,y1,x2,y2;//定义整数类型x1,x2,y1,y2
cin>>n;//输入n的值
for(int i=0;i<n;i++){//for循环,计数器i从0自增到n-1,共循环n次
cin>>x1>>y1>>x2>>y2;//输入x1,y1,x2,y2
a[x1+1][y1+1]++;//a[x1+1][y1+1]自增1
a[x2+1][y1+1]--;//a[x2+1][y1+1]自减1
a[x1+1][y2+1]--;//a[x1+1][y2+1]自减1
a[x2+1][y2+1]++;//a[x2+1][y2+1]自增1
}
long long sum=0;//定义长整数类型变量sum并初始化赋值为0
for(int i=1;i<=20;++i)//for循环,计数器i从1自增到20,共循环20次
for(int j=1;j<=20;++j){//for循环,计数器j从1自增到20,共循环20次
a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];//a[i][j]自增a[i-1][j]+a[i][j-1]-a[i-1][j-1]
//此时 a[i][j]里记录的就是每个点被覆盖的次数
if(a[i][j]>0) sum++;//如果a[i][j]>0,sum自增1
}
cout<<sum<<endl;//输出sum的值
return 0;//主函数结束,返回0
}