【ABC317】summary and solutions
点击查看目录
赛时总结:
A,好题,切了。
B,好题,切了。
C,我脑子有坑吧,我为什么不把 传参,对着回溯 纠结还没调对,临考试结束 10min 切了。
D,看出来是背包 dp 了,不知道多少年没打背包了,妹切。
百度翻译就是歌姬吧
百度翻译就是歌姬吧
百度翻译就是歌姬吧
百度翻译就是歌姬吧
百度翻译就是歌姬吧
百度翻译就是歌姬吧
百度翻译就是歌姬吧
百度翻译就是歌姬吧
百度翻译就是歌姬吧
百度翻译就是歌姬吧
百度翻译就是歌姬吧
百度翻译就是歌姬吧
百度翻译就是歌姬吧
百度翻译就是歌姬吧
赛后总结:寄。
A Potions
Miku's Code
#include<bits/stdc++.h> using namespace std; #define il inline #define rg register int typedef long long ll; int Max(int x,int y)<%if(x<y) return y;return x;%> int Min(int x,int y)<%if(x<y) return x;return y;%> int Abs(int x)<%if(x<0) return x*(-1);return x;%> const int maxn=105; int n,h,x,p[maxn]; int sum=0,cnt; int main(){ scanf("%d %d %d",&n,&h,&x); sum=h; for(rg i=1;i<=n;++i) scanf("%d",&p[i]); for(rg i=1;i<=n;++i){ sum+=p[i]; if(sum>=x) <% cnt=i;break; %> else sum-=p[i]; } printf("%d\n",cnt); return 0; }
B MissingNo
Miku's Code
#include<bits/stdc++.h> using namespace std; #define il inline #define rg register int typedef long long ll; int Max(int x,int y)<%if(x<y) return y;return x;%> int Min(int x,int y)<%if(x<y) return x;return y;%> int Abs(int x)<%if(x<0) return x*(-1);return x;%> const int maxn=105; int n,num[maxn],pos=-1; int main(){ scanf("%d",&n); for(rg i=1;i<=n;++i){ scanf("%d",&num[i]); } sort(num+1,num+1+n); for(rg i=2;i<=n;++i){ if(num[i]!=num[i-1]+1) pos=num[i-1]+1; } printf("%d\n",pos); return 0; }
C Remembering the Days
,DFS 搜索最大权值。
Miku's Code
#include<bits/stdc++.h> using namespace std; #define il inline #define rg register int typedef long long ll; int Max(int x,int y)<%if(x<y) return y;return x;%> int Min(int x,int y)<%if(x<y) return x;return y;%> int Abs(int x)<%if(x<0) return x*(-1);return x;%> const int maxn=15,maxm=50; int n,m,dis,maxx; bool vis[maxn],mj[maxn]; int head[maxm<<1],t; #define next Miku struct edge{ int v,w; int next; };edge e[maxm<<1]; il void add_edge(int u,int v,int w){ e[++t].v=v; e[t].w=w; e[t].next=head[u]; head[u]=t; } il void clear(){ for(rg i=0;i<=maxn-1;++i){ vis[i]=false; } maxx=Max(maxx,dis); dis=0; } il void dfs(int now,int sum){ vis[now]=true; maxx=Max(maxx,sum); for(rg i=head[now];i;i=e[i].next){ int to=e[i].v; if(vis[to]==true) continue; dfs(to,sum+e[i].w); } vis[now]=false; } il void input(){ scanf("%d %d",&n,&m); int a,b,c; for(rg i=1;i<=m;++i){ scanf("%d %d %d",&a,&b,&c); add_edge(a,b,c); add_edge(b,a,c); } } int main(){ input(); for(rg i=1;i<=n;++i){ dfs(i,0); } printf("%d\n",maxx); return 0; }
D President
以席位为背包容量,其值在 到 时,高桥获胜,以转换支持者的选民为代价,做背包 dp 求最小代价即可。
Miku's Code
#include<bits/stdc++.h> using namespace std; #define il inline #define rg register int typedef long long ll; ll Max(ll x,ll y)<%if(x<y) return y;return x;%> ll Min(ll x,ll y)<%if(x<y) return x;return y;%> int Abs(int x)<%if(x<0) return x*(-1);return x;%> const int maxn=105; const ll inf=200708310393939; int n,x[maxn],y[maxn],z[maxn],maxtemp; ll sum; ll f[100050]; void work(){ for(rg i=1;i<=sum;++i) f[i]=inf; for(rg i=1;i<=n;++i){ int w=Max(0,(x[i]+y[i])/2+1-x[i]); for(int j=sum;j>=z[i];--j){ f[j]=Min(f[j],f[j-z[i]]+w); } } } il void input(){ scanf("%d",&n); for(rg i=1;i<=n;++i) scanf("%d %d %d",&x[i],&y[i],&z[i]),sum+=z[i]; } int main(){ input(); work(); ll ans=inf; for(rg i=sum/2+1;i<=sum;++i) ans=Min(ans,f[i]); printf("%lld\n",ans); return 0; }
E Avoid Eye Contact
将守卫能看到的位置标记,BFS 搜索即可。
Miku's Code
#include<bits/stdc++.h> using namespace std; #define il inline #define rg register int typedef long long ll; typedef pair<int,int> PII; ll Max(ll x,ll y)<%if(x<y) return y;return x;%> ll Min(ll x,ll y)<%if(x<y) return x;return y;%> int Abs(int x)<%if(x<0) return x*(-1);return x;%> const int maxn=2050; int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1}; int h,w,stx,sty,tox,toy; char s[maxn][maxn]; int ans[maxn][maxn]; bool vis[maxn][maxn]; il void bfs(){ queue<PII> q; while(!q.empty()) q.pop(); q.push(make_pair(stx,sty)); while(!q.empty()){ PII save=q.front(); q.pop(); for(rg i=0;i<4;++i){ int xx=save.first+dx[i],yy=save.second+dy[i]; if(xx>=1 && xx<=h && yy>=1 && yy<=w && s[xx][yy]!='#' && s[xx][yy]!='<' && s[xx][yy]!='>' && s[xx][yy]!='^' && s[xx][yy]!='v' && vis[xx][yy]==false && ans[xx][yy]==0){ q.push(make_pair(xx,yy)); ans[xx][yy]=ans[save.first][save.second]+1; } } } } il void work(){ for(rg i=1;i<=h;++i){ for(rg j=1;j<=w;++j){ if(s[i][j]=='>'){ int y=j+1; while((s[i][y]=='.' || vis[i][y]) && y<=w) vis[i][y++]=true; } if(s[i][j]=='<'){ int y=j-1; while((s[i][y]=='.' || vis[i][y]) && y>=1) vis[i][y--]=true; } if(s[i][j]=='v'){ int x=i+1; while((s[x][j]=='.' || vis[x][j]) && x<=h) vis[x++][j]=true; } if(s[i][j]=='^'){ int x=i-1; while((s[x][j]=='.' || vis[x][j]) && x>=1) vis[x--][j]=true; } } } } il void input(){ scanf("%d %d",&h,&w); for(rg i=1;i<=h;++i){ for(rg j=1;j<=w;++j){ cin>>s[i][j]; if(s[i][j]=='S') stx=i,sty=j; if(s[i][j]=='G') tox=i,toy=j; } } } int main(){ input(); work(); bfs(); if(ans[tox][toy]) printf("%d\n",ans[tox][toy]); else printf("-1\n"); return 0; }
F Nim
(哈哈,你爹 10 维数位dp来咯)
亦或可以想二进制,所以数位 dp 填二进制数,或许这道题可以给一些启发:
对于亦或和为 ,这一位只有四种可能:,,,。
能填这些数的就直接转移过去,然后就得到答案了。
Miku's Code
#include<bits/stdc++.h> using namespace std; #define il inline #define int long long #define rg register int typedef long double llf; typedef long long ll; typedef pair<int,int> PII; const double eps=1e-8; namespace io{ #if ONLINE_JUDGE char in[1<<20],*p1=in,*p2=in; #define getchar() (p1==p2&&(p2=(p1=in)+fread(in,1,1<<20,stdin),p1==p2)?EOF:*p1++) #endif il ll read(){ char c=getchar(); ll x=0,f=1; while(c<48)<%if(c=='-')f=-1;c=getchar();%> while(c>47)x=(x*10)+(c^48),c=getchar(); return x*f; } il void write(int x){ if(x<0)<%putchar('-');x=~x+1;%> if(x>9) write(x/10); putchar(x%10+'0'); } il int ins(char *str){ int len=0; while(1){ char c=getchar(); if(c!='\n' && c!='\0' && c!='\r') str[++len]=c; else{ break; } } return len; } } using namespace io; int N,a1,a2,a3; ll f[63][20][20][20][2][2][2][2][2][2]; vector<int> num; il void pre(){ N=read(),a1=read(),a2=read(),a3=read(); while(N) <% num.push_back(N&1);N=N>>1; %> for(rg A=0;A<=num.size();++A) for(rg P=0;P<=19;++P) for(rg j=0;j<=19;++j) for(rg F=0;F<=19;++F) for(rg e=0;e<=1;++e) for(rg n=0;n<=1;++n) for(rg g=0;g<=1;++g) for(rg c=0;c<=1;++c) for(rg _=0;_<=1;++_) for(rg __=0;__<=1;++__) f[A][P][j][F][e][n][g][c][_][__]=-1; } ll dfs(int pos,int x,int y,int z,bool flag1,bool flag2,bool flag3,bool mj1,bool mj2,bool mj3){ //pos是当前进行至二进制第几位,x,y,z是当前数%a1,a2,a3,flag1,2,3是当前位是否贴上界,mj1,2,3是其二进制位上的数是否为1 if(pos==-1){ if(x==0 && y==0 && z==0 && mj1==true && mj2==true && mj3==true) return 1; else return 0; } if(~f[pos][x][y][z][flag1][flag2][flag3][mj1][mj2][mj3]) return f[pos][x][y][z][flag1][flag2][flag3][mj1][mj2][mj3]; int res=dfs(pos-1,(x<<1)%a1,(y<<1)%a2,(z<<1)%a3,(flag1==true && (num[pos]==0)),(flag2==true && (num[pos]==0)),(flag3==true && (num[pos]==0)),mj1,mj2,mj3)%mod; // //新的一位上的二进制数数全取0 if((flag1==false || num[pos]==1) && (flag2==false || num[pos]==1)) res=(res+dfs(pos-1,(x<<1|1)%a1,(y<<1|1)%a2,(z<<1)%a3,flag1,flag2,(flag3==true && (num[pos]==0)),1,1,mj3))%mod; if((flag1==false || num[pos]==1) && (flag3==false || num[pos]==1)) res=(res+dfs(pos-1,(x<<1|1)%a1,(y<<1)%a2,(z<<1|1)%a3,flag1,(flag2==true && (num[pos]==0)),flag3,1,mj2,1))%mod; if((flag2==false || num[pos]==1) && (flag3==false || num[pos]==1)) res=(res+dfs(pos-1,(x<<1)%a1,(y<<1|1)%a2,(z<<1|1)%a3,(flag1==true && (num[pos]==0)),flag2,flag3,mj1,1,1))%mod; return f[pos][x][y][z][flag1][flag2][flag3][mj1][mj2][mj3]=res; } signed main(){ pre(); printf("%lld\n",dfs(num.size()-1,0,0,0,1,1,1,0,0,0)); return 0; }
G Rearranging
初学网络流。
看了官方题解。
我们建立二分图的子集,左边的子集代表 行,右边的子集代表 个数,共 个点,显然子集内点没有连边,它是二分图。
而该行内有哪些数就从左子集的代表行的点连向右子集代表数的点连边,有几个连几次。
如样例 #1:
input:
3 2 1 1 2 3 2 3
因此可以找一个图的最大匹配,对于某一列,我们就得到了其数,如#9999ff 色边,其为一列:
1 2 3
然后再删去已经找到过的边,继续找最大匹配,即可。
output:
Yes 1 1 3 2 2 3
Miku's code
#include<bits/stdc++.h> using namespace std; #define il inline #define rg register int #define MYMAX 20070831 typedef long double llf; typedef long long ll; typedef pair<int,int> PII; const double eps=1e-8; #if ONLINE_JUDGE char in[1<<20],*p1=in,*p2=in; #define getchar() (p1==p2&&(p2=(p1=in)+fread(in,1,1<<20,stdin),p1==p2)?EOF:*p1++) #endif inline int read(){ char c=getchar(); int x=0,f=1; while(c<48)<%if(c=='-')f=-1;c=getchar();%> while(c>47)x=(x*10)+(c^48),c=getchar(); return x*f; }const int maxn=205,maxm=40050; int now[maxm<<1],head[maxm<<1],tt=1; #define next Miku struct edge{ int v,w,next; };edge e[maxm<<1]; il void add_edge(int u,int v,int w){ e[++tt].v=v;e[tt].w=w;e[tt].next=head[u];head[u]=tt; e[++tt].v=u;e[tt].w=0;e[tt].next=head[v];head[v]=tt; } int s,t,savt; int n,m,dep[maxn],ans[maxn][maxn]; il void clear(){ for(rg i=1;i<=(n<<1|1);++i) dep[i]=0; } il bool bfs(){ clear(); queue<int> q; while(!q.empty()) q.pop(); q.push(s); dep[s]=1; now[s]=head[s]; while(!q.empty()){ int x=q.front();q.pop(); for(rg i=head[x];i;i=e[i].next){ int to=e[i].v; if(e[i].w>0 && dep[to]==0){ q.push(to); now[to]=head[to]; dep[to]=dep[x]+1; if(to==t) return true; } } } return false; } int dfs(int x,int flow){ if(x==t) return flow; int rest,res=0; for(rg i=head[x];i;i=e[i].next){ int to=e[i].v; if(e[i].w>0 && dep[to]==dep[x]+1){ rest=dfs(to,min(flow,e[i].w)); if(rest==0) dep[to]=0; e[i].w-=rest; e[i^1].w+=rest; res+=rest; flow-=rest; } } return res; } il int get_maxflow(){ int ans=0; while(bfs())<% ans+=dfs(s,MYMAX); %> return ans; } il void input(){ n=read(),m=read(); t=(n<<1|1); int num; for(rg i=1;i<=n;++i){ for(rg j=1;j<=m;++j){ num=read(); add_edge(i,n+num,1); } } savt=tt; for(rg i=1;i<=n;++i)<% add_edge(s,i,1);add_edge(n+i,t,1); %> } int main(){ input(); for(rg j=1;j<=m;++j){ int flow=get_maxflow(); if(flow!=n) <% puts("No");return 0; %> for(rg i=3;i<=savt;i+=2){ //网络流将匹配转为反边,枚举反边 if(e[i].w){ int u=e[i].v,to=e[i^1].v; // cout<<"i="<<i<<"; u="<<u<<"; j="<<j<<"; to="<<to<<endl; ans[u][j]=to-n; e[i].w=0; } } for(rg i=savt+2;i<=tt;i+=2){ if(e[i].w){ e[i^1].w=1; e[i].w=0; } } } puts("Yes"); for(rg i=1;i<=n;++i){ for(rg j=1;j<=m;++j) printf("%d ",ans[i][j]); putchar('\n'); } return 0; }
Ex Walk
洛谷没有翻译,我来胡一个(
翻译
题面翻译:
现有一个点编号为 到 的图,图中每条边满足:
- 设这条边端点分别为 和 ,则 和 满足 或者 。
图中的一条边由 四个长度为 的序列表示,设 表示序列 的第 个元素,序列 同,有以下的含义:
-
如果 ,则有点 有一条边连向它本身。
-
如果 ,则有点 有一条边连向点 。(保证 )
-
如果 ,则有点 有一条边连向点 。(保证 )
-
如果 ,则有点 有一条边连向点 。(保证 )
对于给出的图,定义一条路径的长度是该路径走过的边数,请输出长度为 的以 为起点, 为终点的路径数量,答案对 取模。
。
。
给出的图中没有重边,但可能存在自环。
不会,求教教。
upd 2023/9/9:生成函数,跳了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App