西安集训day4B层考试题解(不要问我为什么来水B层 双连通分量听不懂啊
T1 传送门//密码xjzjd(相聚在吉 交大
大水题2333
用一个map记录一下就好了(一定注意数据会重复出现233 30分的惨痛教训啊
那就直接放代码啦
#include<bits/stdc++.h>
using namespace std;
#define ll long long
inline ll read()
{
ll w=1,s=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<1)+(s<<3)+ch-48;ch=getchar();}
return w*s;
}
int n;
map<int,int>m;
bool mark[310];
int main()
{
n=read();
int x;
while(~scanf("%d",&x)) m[x]++;
for(int i=1;i<=n;i++)
{
memset(mark,0,sizeof mark);
for(int j=1;j<=300;j++)
{
if(m[j])
{
int ans=0,a=j;
while(a)
{
int sum=1,wei=a%10;
a/=10;
for(int k=1;k<=i+1;k++) sum*=wei;
ans+=sum;
if(ans>300) break;
}
if(m[ans]) mark[ans]=1;
}
}
for(int i=1;i<=300;i++) if(mark[i]) m[i]--;
}
for(int i=1;i<=300;i++) while(m[i]) printf("%d ",i),m[i]--;
}
T2 传送门
久违的数学题233
要将n拆成若干个不同的正整数,且要乘积最大
显然相同的数分解为两个数的乘积要比一个数大
所以从2(因为1没用)开始枚举,看看最多能拼出多少个不同的数。
如果有剩余的,就从最后一个数开始依次+1知道没有剩余就好啦 注意要高精乘
#include<bits/stdc++.h>
using namespace std;
#define ll long long
inline int read()
{
int w=1,s=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<1)+(s<<3)+ch-48;ch=getchar();}
return w*s;
}
struct node
{
int a[210];
node(){memset(a,0,sizeof a);}
friend node operator *(node i,node j)
{
node c;
int li=100,lj=100;
while(i.a[li]) li--;
while(j.a[lj]) lj--;
int x=0;
for(int ss=1;ss<=li;ss++)
{
x=0;
for(int dd=1;dd<=lj;dd++)
{
c.a[ss+dd-1]=c.a[ss+dd-1]+x+i.a[ss]*j.a[dd];
x=c.a[ss+dd-1]/10;
c.a[ss+dd-1]%=10;
}
c.a[ss+lj]=x;
}
return c;
}
}s[110];
int f[1010],ans[1010],cnt;
int main()
{
int n=read();
int beg=2;
while(n-beg>=0)
{
f[++cnt]=beg;
n-=beg;
beg++;
}
if(n==beg-1) f[cnt]++,n--;
for(int i=cnt;i>=1&&n>0;i--,n--) f[i]++;
for(int i=1;i<=cnt;i++)
{
if(f[i]<10) s[i].a[1]=f[i];
else
{
s[i].a[1]=f[i]%10;
s[i].a[2]=f[i]/10;
}
}
node x;
x.a[1]=1;
for(int i=1;i<=cnt;i++) x=x*s[i];
int z=100;
while(x.a[z]==0)z--;
for(int i=z;i>=1;i--) printf("%d",x.a[i]);
}
T3 传送门
出现在b层真的毒瘤233(还好数据范围水
直接暴力建图,然后跑dij求出每个点的dis
之后边上两端点便有两种情况
1.两点dis之差>木棍燃烧时间
2.两点dis之差 < 木棍燃烧时间
第一种情况,说明在另一端点到达之前已经烧完了木棍。而第二种会在木棍上发生相遇
对于这两种情况,分别处理出木棍燃烧的时间再将所有求和便是从这一点出发的燃烧时间。
我们再从每一个节点跑一遍最短路就求出最少燃烧时间啦!
代码明天写,晚安