Codeforces Round 635 (Div.2)
吐槽环节
- 比赛就做出
4道,
D fst啦
- 中国场果真毒瘤
A.Ichihime and Triangle
题目意思
Sol
-
shabby题目,因为是随便构造。所以我们只要强制两根长的木棒相等就可以了,保证满足条件的。
- 时间复杂度:
O(1)
Code
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
inline int read()
{
int sum=0,ff=1; char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-1;
ch=getchar();
}
while(isdigit(ch))
sum=sum*10+(ch^48),ch=getchar();
return sum*ff;
}
int Q,a,b,c,d;
int main()
{
Q=read();
for (;Q--;)
{
a=read();
b=read();
c=read();
d=read();
printf("%d %d %d\n",b,c,c);
}
return 0;
}
B.Kana and Dragon Quest game
题目意思
Sol
- 又是简单题(
A,B两题共
6分钟就可以做完很正常。。。
- 我们就先不停地能使用操作
1就用直到
x≤10,我们再用操作
2。然后就判断这样过后剩余的
x与
0比一比就好了。
- 时间复杂度:
O(logx)
Code
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
inline int read()
{
int sum=0,ff=1; char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-1;
ch=getchar();
}
while(isdigit(ch))
sum=sum*10+(ch^48),ch=getchar();
return sum*ff;
}
int Q,a,b,c,d;
int main()
{
Q=read();
for (;Q--;)
{
a=read();
b=read();
c=read();
while(b>0&&a>10)
{
a=a/2+10;
b--;
}
if(a<=c*10) puts("YES");
else puts("NO");
}
return 0;
}
C.Linova and Kingdom
题目意思
Sol
- 一道简单的结论题目
- 那么选节点
x时,增加的答案
Depx−1,因为它成功变为了那个选择点节点,同时减少的答案为
Sizx−1,因为它的子树节点都少了一个。
- 那么答案就是前
K大的
Depx−Sizx
- 时间复杂度:
O(nlogn)
Code
#include <bits/stdc++.h>
#define pb push_back
#define int long long
using namespace std;
inline int read()
{
int sum=0,ff=1; char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-1;
ch=getchar();
}
while(isdigit(ch))
sum=sum*10+(ch^48),ch=getchar();
return sum*ff;
}
const int N=2e5+5;
int n,m,dep[N],a[N],siz[N],ans;
vector<int> G[N];
inline void dfs(int u,int fa)
{
dep[u]=dep[fa]+1;
siz[u]=1;
for ( int i=0;i<G[u].size();i++ )
{
int v=G[u][i];
if(v==fa) continue;
dfs(v,u);
siz[u]+=siz[v];
}
a[u]=dep[u]-siz[u];
}
signed main()
{
n=read();
m=read();
for ( int i=1;i<n;i++ )
{
int x,y;
x=read();
y=read();
G[x].pb(y);
G[y].pb(x);
}
dfs(1,0);
sort(a+1,a+n+1);
reverse(a+1,a+n+1);
for ( int i=1;i<=m;i++ ) ans+=a[i];
printf("%lld\n",ans);
return 0;
}
D.Xenia and Colorful Gems
题目意思
Sol
- 一道比较简单的题目,但是比赛时
fst啦,赛后仔细想想开始想错了。
- 我们考虑一个简单的性质:就是如果选了
A中的一个球
x,那么
B,C中想让答案小是不是只要试图去接近他就可以了。然后
B,C同理。
- 这样我们就对
A,B,C各自做一遍。然后找到对应另外两个中与他接近的(具体地看代码吧
- 时间复杂度:
O(k∗nlogn),
k为常数
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
int sum=0,ff=1; char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-1;
ch=getchar();
}
while(isdigit(ch))
sum=sum*10+(ch^48),ch=getchar();
return sum*ff;
}
const int N=1e5+5;
int Q,na,nb,nc,ans;
int a[N],b[N],c[N];
inline int Calc(int x,int y,int z)
{
return (x-y)*(x-y)+(z-x)*(z-x)+(y-z)*(y-z);
}
signed main()
{
Q=read();
for (;Q--;)
{
na=read(),nb=read(),nc=read();
for ( int i=1;i<=na;i++ ) a[i]=read();
for ( int i=1;i<=nb;i++ ) b[i]=read();
for ( int i=1;i<=nc;i++ ) c[i]=read();
sort(a+1,a+na+1);
sort(b+1,b+nb+1);
sort(c+1,c+nc+1);
ans=1e19;
for ( int i=1;i<=na;i++ )
{
int pb=upper_bound(b+1,b+nb+1,a[i])-b;
int pc=upper_bound(c+1,c+nc+1,a[i])-c;
int pbb=pb-1,pcc=pc-1;
if(pb<=nb)
{
if(pc<=nc) ans=min(ans,Calc(a[i],b[pb],c[pc]));
if(pcc>=1) ans=min(ans,Calc(a[i],b[pb],c[pcc]));
}
if(pbb>=1)
{
if(pc<=nc) ans=min(ans,Calc(a[i],b[pbb],c[pc]));
if(pcc>=1) ans=min(ans,Calc(a[i],b[pbb],c[pcc]));
}
}
for ( int i=1;i<=nb;i++ )
{
int pa=upper_bound(a+1,a+na+1,b[i])-a;
int pc=upper_bound(c+1,c+nc+1,b[i])-c;
int paa=pa-1,pcc=pc-1;
if(pa<=na)
{
if(pc<=nc) ans=min(ans,Calc(b[i],a[pa],c[pc]));
if(pcc>=1) ans=min(ans,Calc(b[i],a[pa],c[pcc]));
}
if(paa>=1)
{
if(pc<=nc) ans=min(ans,Calc(b[i],a[paa],c[pc]));
if(pcc>=1) ans=min(ans,Calc(b[i],a[paa],c[pcc]));
}
}
for ( int i=1;i<=nc;i++ )
{
int pb=upper_bound(b+1,b+nb+1,c[i])-b;
int pa=upper_bound(a+1,a+na+1,c[i])-a;
int pbb=pb-1,paa=pa-1;
if(pb<=nb)
{
if(pa<=na) ans=min(ans,Calc(c[i],b[pb],a[pa]));
if(paa>=1) ans=min(ans,Calc(c[i],b[pb],a[paa]));
}
if(pbb>=1)
{
if(pa<=na) ans=min(ans,Calc(c[i],b[pbb],a[pa]));
if(paa>=1) ans=min(ans,Calc(c[i],b[pbb],a[paa]));
}
}
printf("%lld\n",ans);
}
return 0;
}
E.Kaavi and Magic Spell
题目意思
Sol
- 一道区间
DP题目
- 首先我们考虑如果那个串的长度已经大于
∣T∣,且前缀为
T后面就可以任意填了。
- 那么我们设
fl,r表示填的那个串与
T匹配了
[l,r]的方案数
- 那么转移如下
-
fl,r=fl,r+fl+1,r[Si=Tl]
-
fl,r=fl,r+fl,r−1[Si=Tr]
- 对于
i>m的两个都可以转移
- 那么
ans=∑i=mnf1,i
- 时间复杂度:
O(n2)
Code
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
inline int read()
{
int sum=0,ff=1; char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-1;
ch=getchar();
}
while(isdigit(ch))
sum=sum*10+(ch^48),ch=getchar();
return sum*ff;
}
const int N=3005;
const int mo=998244353;
int n,m,f[N][N],ans;
char ch[N],th[N];
int main()
{
scanf("%s",ch+1);
scanf("%s",th+1);
n=strlen(ch+1);
m=strlen(th+1);
for ( int i=1;i<=n+1;i++ ) f[i][i-1]=1;
for ( int i=1,len=1;i<=n;i++,len++ )
for ( int l=1,r=l+len-1;r<=n;l++,r++ )
{
if(l>m||ch[i]==th[l])
f[l][r]=(f[l][r]+f[l+1][r])%mo;
if(r>m||ch[i]==th[r])
f[l][r]=(f[l][r]+f[l][r-1])%mo;
}
for ( int i=m;i<=n;i++ ) ans=(ans+f[1][i])%mo;
printf("%d\n",ans);
return 0;
}