BNDS 2024/4/6模拟赛题解
T1 方程
描述
给出非负整数
输入
输入数据,包含一个非负整数
输出
输出数据,包含一个非负整数表示解的数量。
数据范围
40%的数据,
60%的数据,
100%的数据,
分析
看到这个数据范围,应该只能从
移项后可得
注意,我们对于这个
所以,我们只需要从小到大枚举
时间复杂度
代码
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
ll n,ans;
int main(){
scanf("%lld",&n);
for(ll z=0;z*z*z<=n;z++)
ans+=ll(sqrt(n-z*z*z))+1ll;
printf("%lld",ans);
return 0;
}
T2 打砖块
描述
在一个凹槽中放置了
如果你要敲掉第
你现在可以敲掉最多m块砖,求得分最多能有多少。
输入
输入的第一行为两个正整数
输出
输出仅一行为一个正整数,表示被敲掉砖块的最大价值总和。
数据范围
对于
对于
分析
一眼DP。
不过,看图之后发现,这个图并不存在决策单调性的性质。
不过旋转之后,就可以变成前
这里通过一个输入就能完成旋转:
for(int j=1;j<=n;j++){
for(int i=n;i>=j;i--){
scanf("%d",&brick[i][j]);
}
}
设
还有就是记得提前算每行的前缀和
PS:这道题的限制条件挺多的...所以写出了诸如
最坏时间复杂度
代码
#include<bits/stdc++.h>
#define N 55
using namespace std;
int n,m,brick[N][N],dp[N][N][2005],sum[N][N];
int ans;
int main(){
scanf("%d%d",&n,&m);
for(int j=1;j<=n;j++){
for(int i=n;i>=j;i--){
scanf("%d",&brick[i][j]);
}
}
/*
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
cout<<brick[i][j]<<' ';
}
cout<<endl;
}*/
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
sum[i][j]=sum[i][j-1]+brick[i][j];
}
}
for(int i=1;i<=n;i++){
int mxg=min((i*(i+1))>>1,m),mxj,mxk;
for(int g=0;g<=mxg;g++){
mxj=min(i,g);
for(int j=0;j<=mxj;j++){
mxk=min(g-j,i-1);
for(int k=max(j-1,0);k<=mxk;k++){
if(dp[i-1][k][g-j]+sum[i][j]>dp[i][j][g])
dp[i][j][g]=dp[i-1][k][g-j]+sum[i][j];
}
}
}
}
for(int j=0;j<=n;j++){
if(dp[n][j][m]>ans)
ans=dp[n][j][m];
}
printf("%d",ans);
return 0;
}
T3 打砖块
描述
有两个长度为
输入
第一行输入一个正整数
输出
输出仅一行,包含
数据范围
对于
对于
分析
如果这道题只要
如果你想要AC的话...
我们不妨建立一个优先队列,开始时将
代码
#include<bits/stdc++.h>
#define N 100005
using namespace std;
using PII=pair<int,int>;
bool cmp(PII a,PII b){
return a.first<b.first;
}
priority_queue<PII,vector<PII>,greater<PII> > q;
int n,a[N],b[N],cnt[N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
cnt[i]=1;
scanf("%d",a+i);
}
for(int i=1;i<=n;i++){
scanf("%d",b+i);
}
sort(a+1,a+n+1);
sort(b+1,b+n+1);
for(int i=1;i<=n;i++){
q.push(make_pair(a[i]+b[1],i));
}
for(int i=1;i<=n;i++){
PII tmp=q.top();
q.pop();
printf("%d ",tmp.first);
q.push(make_pair(a[tmp.second]+b[++cnt[tmp.second]],tmp.second));
}
return 0;
}
T4 最小密度路径
描述
给出了一张有
输入
第 $1 行包括2个整数
第
第
接下来
输出
对于每个询问输出一行,表示该询问的最小密度路径的密度(保留
如果不存在从
数据范围
对于
对于
分析
考场上时间不够了。(主要是T2时间想的太久了)
所以写了个dfs爆搜。(喜得54分)
后来想了下,看到了数据范围,用Floyd应该没问题?再单独加一个记录多少步的数组,然后枚举一遍应该就行了。
(暴力DFS)代码
#include<bits/stdc++.h>
#define N 100005
#define M 55
using namespace std;
int n,m,Q;
const double INF=1145141919810.0;
struct EDGE{
int to,nxt,v;
}e[N];
int head[N],cnt=0;
double dis[M][M];
void add(int u,int v,int w){
e[++cnt].to=v;
e[cnt].v=w;
e[cnt].nxt=head[u];
head[u]=cnt;
}
void dfs(int x,double sum,int edgeCnt,int origin)
{
if(x!=origin)
dis[origin][x]=min(dis[origin][x],sum/double(edgeCnt));
for(int i=head[x];i;i=e[i].nxt){
dfs(e[i].to,sum+double(e[i].v),edgeCnt+1,origin);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
dis[i][j]=INF;
}
dis[i][i]=0;
}
for(int i=1;i<=n;i++)
dfs(i,0,0,i);
scanf("%d",&Q);
while(Q--){
int x,y;
scanf("%d%d",&x,&y);
if(dis[x][y]==INF)
printf("OMG!\n");
else
printf("%.3lf\n",dis[x][y]);
}
return 0;
}
AC代码
#define N 55
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const int INF = 0x3f3f3f3f;
int n, m, q;
double map[N][N][N];
double d[N][N];
inline void add(int from, int to, double dist) {
map[from][to][1] = min(map[from][to][1], dist);
}
inline void den() {
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
for (int k = 1; k <= n; k++)
if (map[i][j][k] != INF)
d[i][j] = min(d[i][j], map[i][j][k] / k);
}
void floyd() {
for (int t = 2; t <= n; t++)
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
map[i][j][t] = min(map[i][j][t], map[i][k][t - 1] + map[k][j][1]);
den();
}
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
for (int k = 1; k <= n; k++)
map[i][j][k] = INF;
d[i][j] = INF;
}
for (int i = 1; i <= m; i++) {
int x, y, v;
scanf("%d%d%d", &x, &y, &v);
add(x, y, v);
}
floyd();
scanf("%d", &q);
for (int i = 1; i <= q; i++) {
int x, y;
scanf("%d%d", &x, &y);
if (d[x][y] == INF)
printf("OMG!\n");
else
printf("%0.3lf\n", d[x][y]);
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 为DeepSeek添加本地知识库
· 精选4款基于.NET开源、功能强大的通讯调试工具
· DeepSeek智能编程
· 大模型工具KTransformer的安装
· [计算机/硬件/GPU] 显卡