2023.3.7拷逝题解
T1 草种子(dendro)
由题目可知,每一列最多有两个草种子,每一行最多有两个草种子。
设当前要在
递归边界:
当
当
当
当
#include<iostream>
#include<cstdio>
using namespace std;
long long t,n,m;
long long dfs(long long a,long long b){
if(a==1&&b==1)
return 1;
else if(a==1&&b==2)
return 2;
else if(a==2&&b==1)
return 2;
else if(a==2&&b==2)
return 2;
if(a<b)
swap(a,b);
long long d=a-b;
if(a>=b*2)
return b*2;
if(d>0)
return dfs(a-d*2,b-d)+d*2;
if(d==0)
return dfs(a%3,b%3)+a/3*4;
}
int main(){
//freopen("dendro.in","r",stdin);
//freopen("dendro.out","w",stdout);
scanf("%lld",&t);
while(t--){
scanf("%lld%lld",&n,&m);
if(n<m)
swap(n,m);
printf("%lld\n",dfs(n,m));
}
fclose(stdin);fclose(stdout);
return 0;
}
T2 数列(seq)
不难发现这道题需要搜索,但是如果是正常的搜索会超时,所以我们需要双向搜索。具体细节见代码。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long n,a[15],s,rsum[15],ans,f[15][50],cnt,sum[2000005],n1;
bool cmp(long long x,long long y){
return x>y;
}
long long fast_mul(long long x,long long y){
long long sum=x;x=1;
while(y){
if(y&1){
x*=sum;
if(x>1e9)
return 2e9;
}
sum*=sum;
y>>=1;
if(sum>1e9&&y)
return 2e9;
}
return x;
}
void dfs1(long long x,long long y){
if(y>s)
return ;
if(x==n1+1&&y<=s){
sum[++cnt]=y;
return ;
}
for(int i=1;y+f[x][i]<=s;++i)
dfs1(x+1,y+f[x][i]);
}
void dfs2(long long x,long long y){
if(y>s)
return ;
if(x==n+1&&y<=s){
long long pos=upper_bound(sum+1,sum+cnt+1,s-y)-sum;
while(pos>cnt||sum[pos]+y>s)
--pos;
ans+=pos;
return ;
}
for(int i=1;y+f[x][i]<=s;++i)
dfs2(x+1,y+f[x][i]);
}
int main(){
//freopen("seq.in","r",stdin);
//freopen("seq.out","w",stdout);
scanf("%lld%lld",&n,&s);
for(int i=1;i<=n;++i)
scanf("%lld",&a[i]);
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;++i)
for(int j=1;j<=35;++j)
f[i][j]=fast_mul(a[i],j);
n1=(1+n)>>1;
dfs1(1,0);
sort(sum+1,sum+cnt+1);
dfs2(n1+1,0);
printf("%lld\n",ans);
fclose(stdin);fclose(stdout);
return 0;
}
T3 虚空终端(terminal)
我们将生论派看作 0 号节点,名论派看作
只有
只有
只有
有
分别按照上述四种情况连边,然后跑四次最小生成树,答案就是四次最小生成树的最小值。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long n,m,tot,x[500005],y[500005],a[500005],b[500005],z[500005],fa[500005],ans,sum,cnt;
struct node{
long long u,v,w;
} e[1000005];
bool cmp(node a,node b){
return a.w<b.w;
}
long long _find(long long x){
if(fa[x]==x)
return x;
return fa[x]=_find(fa[x]);
}
void f(long long edge){
sort(e+1,e+tot+1,cmp);
for(int i=0;i<=n+1;++i)
fa[i]=i;
sum=cnt=0;
for(int i=1;i<=tot;++i){
long long a=_find(e[i].u),b=_find(e[i].v);
if(a!=b){
fa[a]=b;++cnt;sum+=e[i].w;
}
if(cnt>=edge)
break;
}
if(cnt==edge)
ans=min(ans,sum);
}
int main(){
//freopen("terminal.in","r",stdin);
//freopen("terminal.out","w",stdout);
scanf("%lld%lld",&n,&m);
ans=1e18;
for(int i=1;i<=n;++i)
scanf("%lld",&x[i]);
for(int i=1;i<=n;++i)
scanf("%lld",&y[i]);
for(int i=1;i<=m;++i){
scanf("%lld%lld%lld",&a[i],&b[i],&z[i]);
e[++tot].u=a[i],e[tot].v=b[i],e[tot].w=z[i];
}
f(n-1);
tot=0;
for(int i=1;i<=m;++i)
e[++tot].u=a[i],e[tot].v=b[i],e[tot].w=z[i];
for(int i=1;i<=n;++i)
e[++tot].u=0,e[tot].v=i,e[tot].w=x[i];
f(n);
tot=0;
for(int i=1;i<=m;++i)
e[++tot].u=a[i],e[tot].v=b[i],e[tot].w=z[i];
for(int i=1;i<=n;++i)
e[++tot].u=n+1,e[tot].v=i,e[tot].w=y[i];
f(n);
tot=0;
for(int i=1;i<=m;++i)
e[++tot].u=a[i],e[tot].v=b[i],e[tot].w=z[i];
for(int i=1;i<=n;++i){
e[++tot].u=0,e[tot].v=i,e[tot].w=x[i];
e[++tot].u=n+1,e[tot].v=i,e[tot].w=y[i];
}
f(n+1);
printf("%lld\n",ans);
fclose(stdin);fclose(stdout);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探