今日题目难度较大,三道题均来自洛谷,最后一题有些问题还没找出来,大概晚上更新
1.马的遍历
思路:DFS做法
#include<bits/stdc++.h>
using namespace std;
int n,m,x,y;
int dx[8]={2,-2,2,-2,-1,1,-1,1};
int dy[8]={1,1,-1,-1,2,2,-2,-2};
// 标记马的行走方向
int ans[401][401];//每个点的步数
int check(int a,int b)
//检查是否越界
{
if(a<1||a>n||b<1||b>m)
return 0;
return 1;
}
void dfs(int a,int b,int sum)
//a和b是当前搜到的坐标,sum为步数
{
int nx,ny;
ans[a][b]=sum;//将答案标记
for(int i=0;i<8;i++)
//搜索八个方向
{
nx=a+dx[i];
ny=b+dy[i];
//扩展新点
if(check(nx,ny)&&(sum+1<ans[nx][ny]||ans[nx][ny]==-1))
//步数比原先搜到的小或没搜到过
dfs(nx,ny,sum+1);//搜索下一个
}
}
int main()
{
cin>>n>>m;
cin>>x>>y;
memset(ans,-1,sizeof(ans));//初始化
dfs(x,y,0);//搜索
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
printf("%-5d",ans[i][j]);
cout<<endl;
}//输出
return 0;
}
2.切绳子
思路: 二分中比较坑的一题,可以先把小数*100化为整数比较简单,二分时mid=(f+r+1)/2;千万记住+1,否则会炸,二分移动端点条件 ans和k的关系
if(ans<k)r=mid-1;
else l=mid;
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<cstdlib>
using namespace std;
long long n,k,s[10005],ans,l,r,sum,mid;
double s1[10005],t;
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)cin>>s1[i],s[i]=s1[i]*100,ans=ans+s[i];
l=0,r=ans/k+1;
while(l<r)
{
mid=(l+r+1)/2;
ans=0;
for(int i=1;i<=n;i++)ans=ans+s[i]/mid;
if(ans<k)r=mid-1;
else l=mid;
}
t=r*1.00/100;
printf("%.2lf\n",t);
return 0;
}
3.导弹拦截(待更新)
思路:这道题就是要求一个最长单调不升子序列和一个最长单调上升子序列。
//问题主要是求解最长上升子序列
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
int m;
cin>>m;
int *p = new int[m];
int *dp = new int[m];
for(int i = 0; i < m; i ++)
{
cin>>p[i];
dp[i] = 1;
}
for(int i = 0; i < m; i ++)
{
for(int j = 0; j < i; j ++) //在这里可以采用折半查找可以降低时间复杂度,为了方便,不掩饰
{
if(p[i] > p[j])
{
dp[i] = max(dp[j] + 1, dp[i]);
}
}
}
int max = dp[0];
for(int i = 0; i < m; i ++)
{
if(max < dp[i])
{
max = dp[i];
}
}
cout<<max;
}
附上检测不通过结果图
这道题有些问题,有没有大佬帮忙看下,想一个下午了
最后,蓝桥杯比赛在即,近30天的冲刺也告一段落,希望大家都能考出好的成绩 ,这两天先休息好,为后天比赛做准备,xdm我希望在省赛的赛场上见到各位!