AtCoder Beginner Contest 387 赛后复盘
省流:A,B,C,D,F
A - B
模拟即可。
C
数位 dp。
首先我们先将问题转换为
设
我们设
那么每一次向下搜索,当枚举当前位是
要么就是有前导零,此时这一位为首位,那么
要么就是没有前导零,此时只有
要记忆化搜索,数位 dp 的时间复杂度才是对的。
点击查看代码
#include<bits/stdc++.h>
#define int ll
#define ll long long
#define i128 __int128
#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
#define fst first
#define scd second
#define dbg puts("IAKIOI")
using namespace std;
int read() {
int x=0,f=1; char c=getchar();
for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1);
for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }
const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }
#define maxn 200050
int l,r;
int f[21][11][2][2];//位数,首位数,上限,前导零
int num[21],top;
int dfs(int dep,int mx,int lim,int ze) {
if(!dep) return 1;
if(f[dep][mx][lim][ze]!=-1) return f[dep][mx][lim][ze];
int res=0;
For(i,0,9) if((!lim)||i<=num[dep]) {
if(ze) res+=dfs(dep-1,i,((i==num[dep])&&lim),((i==0)&&ze));
else if(i<mx) res+=dfs(dep-1,mx,((i==num[dep])&&lim),0);
}
return f[dep][mx][lim][ze]=res;
}
int work(int x) {
m1(f);
m0(num);
top=0;
while(x) {
num[++top]=x%10;
x/=10;
}
if(top<=1) return num[1]+1;
return dfs(top,10,1,1);
}
signed main() {
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
// int _=1;
// _=read();
cin>>l>>r;
cout<<work(r)-work(l-1);
return 0;
}
D
简单搜索。
我们对于每一个点额外记录一维表示转移过来是竖着还是横着,剩下就是 bfs 了。
点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define i128 __int128
#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
#define fst first
#define scd second
#define dbg puts("IAKIOI")
using namespace std;
int read() {
int x=0,f=1; char c=getchar();
for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1);
for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }
const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }
#define maxn 1050
bool vis[2][maxn][maxn];
int h,w;
char mp[maxn][maxn];
int sx,sy,ex,ey;
int dx[5]={0,1,-1,0,0},dy[5]={0,0,0,1,-1};
struct node {
int a,b,c,d;
};
void work() {
cin>>h>>w;
For(i,1,h) For(j,1,w) {
cin>>mp[i][j];
if(mp[i][j]=='S')
sx=i,sy=j;
if(mp[i][j]=='G')
ex=i,ey=j;
}
queue<node>q;
q.push({sx,sy,0,1});
q.push({sx,sy,0,2});
while(!q.empty()) {
auto [x,y,cnt,flg]=q.front();
q.pop();
if(vis[flg-1][x][y]) continue;
vis[flg-1][x][y]=1;
if(x==ex&&y==ey) return cout<<cnt,void();
For(i,1,4) if((i+1)/2!=flg) {
int X=x+dx[i],Y=y+dy[i];
if(X>0&&X<=h&&Y>0&&Y<=w&&mp[X][Y]!='#'&&!vis[((i+1)/2)-1][X][Y])
q.push({X,Y,cnt+1,(i+1)/2});
}
}
cout<<-1;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int _=1;
// _=read();
For(i,1,_) {
work();
}
return 0;
}
E
首先,对于
当
那么我们还知道,当一个数的数位和为
所以我们只要有一个数
因为
点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define i128 __int128
#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
#define fst first
#define scd second
#define dbg puts("IAKIOI")
using namespace std;
int read() {
int x=0,f=1; char c=getchar();
for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1);
for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }
const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }
#define maxn 200050
string s;
int check(int x) {
int res=0;
while(x) {
res+=x%10;
x/=10;
}
return res;
}
void work() {
cin>>s;
if(s.size()<6) {
int x=stol(s);
For(i,x,x+x-1) {
if(i%check(i)==0&&(i+1)%check(i+1)==0) {
cout<<i<<'\n';
return void();
}
}
cout<<-1;
return void();
}
int n=(s[0]-48)*100+(s[1]-48)*10+(s[2]-48);
For(i,n+1,n+n-1) {
if(check(i)==8) {
cout<<i;
For(j,1,s.size()-3) cout<<0;
return void();
}
}
cout<<-1;
}
signed main() {
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
int _=1;
// _=read();
For(i,1,_) {
work();
}
return 0;
}
F
你是一名 OIer。你在打 abc387 的时候看到了这道题。
你并不会 E,所以你打算死磕 F。
你发现这个大小关系可以转换成图论的连边,然后再跑 dp 就好了。
你发现如果图上有环的话,那么环上的数都相等。于是你立马想到了缩点。
你立马敲完了 Tarjan 缩点,虽然你随后发现这张图一定是基环树森林,所以只需要跑拓扑就可以缩点了。
然后就是 dp。
你设
然后你列出了转移方程,当
你发现这个 dp 是
就在你要丧失信心时,你突然发现 dp 的
你迅速的打完了这个优化,又突然发现你不会统计方案。
你发现由于每个点只有一条出边,所以这个图形最后只会是一条条链,那么你需要的答案就是链的终点的所有值之积,用乘法原理计算即可。
这是你的代码:
点击查看代码
#include<bits/stdc++.h>
#define int ll
#define ll long long
#define i128 __int128
#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
#define fst first
#define scd second
#define dbg puts("IAKIOI")
using namespace std;
int read() {
int x=0,f=1; char c=getchar();
for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1);
for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }
const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }
#define maxn 2250
int n,m;
int a[maxn];
vector<int> G[maxn];
int dfn[maxn],dfncnt,low[maxn];
int stk[maxn],stktop;
bool instk[maxn];
int bel[maxn],belcnt;
void Tarjan(int u) {
low[u]=dfn[u]=++dfncnt;
instk[(stk[++stktop]=u)]=1;
for(auto v:G[u]) {
if(!dfn[v]) Tarjan(v),low[u]=min(low[u],low[v]);
else if(instk[v]) low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]) {
belcnt++;
while(1) {
int v=stk[stktop--];
instk[v]=0;
bel[v]=belcnt;
if(u==v) break;
}
}
}
int deg[maxn];
int f[maxn][maxn];
void work() {
in2(n,m);
For(i,1,n) {
in1(a[i]);
G[i].push_back(a[i]);
}
For(i,1,n) if(!dfn[i]) Tarjan(i);
For(i,1,n) G[i].clear();
For(i,1,n) if(bel[i]!=bel[a[i]]) G[bel[i]].push_back(bel[a[i]]),deg[bel[a[i]]]++;
queue<int> q;
For(i,1,belcnt) if(!deg[i]) q.push(i);
For(i,1,belcnt) For(j,1,m) f[i][j]=1;
int ans=1;
while(!q.empty()) {
int u=q.front();
q.pop();
For(i,1,m) (f[u][i]+=f[u][i-1])%=mod;
if(G[u].size()==0) (ans*=f[u][m])%=mod;
for(auto v:G[u]) {
deg[v]--;
For(i,1,m) (f[v][i]*=f[u][i])%=mod;
if(deg[v]==0) q.push(v);
}
}
cout<<ans;
}
signed main() {
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
int _=1;
// _=read();
For(i,1,_) {
work();
}
return 0;
}
你交了上去,并获得了 550pts,这使得你的排名暴涨。
你笑了出来,笑着笑着,你感觉眼前一阵眩晕。同时有一个熟悉的声音呼唤着你:“起床了”。
你醒了,看到了旁边把你摇醒的同学,指了指台上的道法老师。
原来这一切都只是上道法课时的睡觉的幻想罢了。
本文来自博客园,作者:coding_goat_qwq,转载请注明原文链接:https://www.cnblogs.com/CodingGoat/p/18652570
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!