2019 CCPC-Wannafly Winter Camp Div2 Day7
题目难度按照难易程度:
G签到题 暴力枚举哪个是机器人 然后暴力判断它之前有多少个机器人 然后得出答案更新最小值
#include<bits/stdc++.h> #define ll long long using namespace std; int a[105][105]; int vis[105]; int main() { int n,m; cin>>n>>m; for(int j=1; j<=m; j++) { int k; cin>>k; a[j][1]=k; for(int i=2; i<=k+1; i++) { cin>>a[j][i]; } } int ans=n; for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); queue<int> q; q.push(i); vis[i]=1; int cnt=1; while(!q.empty()) { int u=q.front(); q.pop(); for(int j=1;j<=m;j++) { int stp=0; for(int k=2;k<=a[j][1]+1;k++) { if(a[j][k]==u) { stp=k; break; } } for(int k=2;k<stp;k++) { if(!vis[a[j][k]]) { q.push(a[j][k]); vis[a[j][k]]=1; cnt++; } } } } if(ans>cnt) ans=cnt; } cout<<ans<<endl; }
A ans=max(ans,step[i]+nums[step[i]]-1) 画图可知
#include<bits/stdc++.h> #define ll long long const int maxn = 100005; using namespace std; int a[maxn],head[maxn],To[maxn*2],Next[maxn*2],vis[maxn],num[maxn],step[maxn]; int cnt; struct node { int u,stp; }; void add(int u,int v) { Next[++cnt]=head[u]; head[u]=cnt; To[cnt]=v; } int main() { int n,ans=0; cin>>n; for(int i=1; i<=n; i++) { cin>>a[i]; if(a[i]==1) ans++; } memset(head,-1,sizeof(head)); for(int i=1; i<n; i++) { int u,v; cin>>u>>v; add(u,v); add(v,u); } queue<node> q; q.push(node{1,0}); while(!q.empty()) { node p=q.front(); q.pop(); if(vis[p.u]) continue; vis[p.u]=1; for(int i=head[p.u]; i!=-1; i=Next[i]) { int v=To[i]; if(!vis[v]) { q.push(node{v,p.stp+1}); num[p.stp+1]++; step[v]=p.stp+1; } } } for(int i=2; i<=n; i++) { ans=max(ans,step[i]+num[step[i]]-1); } cout<<ans<<endl; }
E 比赛的时候写了个傻逼暴力,各种情况没考虑,赛后想到其实可以暴力建边跑topsort。我们需要填a位置的时候,如果a不是正好对应的a[i]%n时,它就是由其他平移过来的,所以我们只需要把它之前的位置全部建一条边到这个点即可(及+度)。div1 的此题,由于建边的时候是某个区间都要连a位置,可以线段树优化建边即可满足div1.
#include<bits/stdc++.h> #define ll long long const int maxn = 1005; using namespace std; int head[maxn],To[maxn*2000],Next[maxn*2000]; int cnt,b[maxn],in[maxn]; vector<int> v; inline void add(int u,int v) { Next[++cnt]=head[u]; head[u]=cnt; To[cnt]=v; } struct node { int v,d; bool friend operator < (node x,node y) { return x.d>y.d; } }; void topsort(int n) { priority_queue<node> q; for(int i=0;i<n;i++) { if(b[b[i]%n]==b[i]) q.push(node{i,b[i]}); else { for(int j=b[i]%n;;j++) { int k=j%n; if(k==i) break; add(k,i); in[i]++; } } } while(!q.empty()) { node p=q.top(); q.pop(); int u=p.v; v.push_back(u); for(int i=head[u];~i;i=Next[i]) { int V=To[i]; if(--in[V]==0) q.push(node{V,b[V]}); } } } int main() { int n; cin>>n; for(int i=0;i<n;i++) { cin>>b[i]; } memset(head,-1,sizeof(head)); topsort(n); for(auto x:v) cout<<b[x]<<" "; }
比赛时候就三题,其他Dai更(代补 数位DP)