这一场div3整体比较简单注意细节即可
目录
A. Wrong Subtraction
B. Two-gram
C. Less or Equal
D. Divide by three, multiply by two
E. Cyclic Components
F. Consecutive Subsequence
A. Wrong Subtraction
按照题目意思直接模拟操作次数即可
void solve(){cin>>n>>m;while(m--){int t=n%10;if(t) n--;else n/=10;}cout<<n<<endl;return ;
}
B. Two-gram
按照字符串也是直接模拟即可
void solve(){map<string,int> mp;cin>>n;string s; cin>>s;string ans=" ";for(int i=1;i<n;i++){string now;now+=s[i-1];now+=s[i];mp[now]++;if(mp[now]>mp[ans]){ans=now;}}cout<<ans<<endl;return ;
}
C. Less or Equal
我们可以发现答案是具有二分性质的如果一个数越大少于他的数只会变多所以考虑二分即可
void solve(){cin>>n>>m;vector<int> a(n);for(auto&v:a) cin>>v;sort(a.begin(),a.end());auto check = [&](int x){int cnt=0;for(auto&v:a) cnt+=v<=x;return cnt;};int l=1,r=1e9;while(l<r){int mid=l+r+1>>1;if(check(mid)<=m) l=mid;else r=mid-1;}cout<<(check(l)==m ? l : -1)<<endl;return ;
}
D. Divide by three, multiply by two
每一个数的前后数一定是一一对应的所以可以直接记录,然后我们考虑求倒着用下一位记录前一位这样就可以直接倒推(同时注意开longlong)
void solve(){cin>>n;vector<LL> a(n);map<LL,LL> cnt,pre;for(auto&v:a){cin>>v;cnt[v]++;}LL last;for(auto&v:a){if(cnt.count(2*v)) pre[2*v]=v;else if(v%3==0 && cnt.count(v/3))pre[v/3]=v;else last=v;}vector<LL> ans;ans.push_back(last);while(pre.count(last)){last=pre[last];ans.push_back(last);}reverse(ans.begin(),ans.end());for(auto&v:ans) cout<<v<<' ';cout<<endl;return ;
}
E. Cyclic Components
我们发现一个环上的一定都是每个点都是有两个子节点,这就是这题的性质然后dfs即可
bitset<N> st;
bool ok;
void dfs(int u){st[u]=true;if(g[u].size()!=2) ok=false;for(auto&v:g[u]){if(!st[v])dfs(v); }
}void solve(){cin>>n>>m;while(m--){int a,b; cin>>a>>b;g[a].push_back(b);g[b].push_back(a);}int ans=0;for(int i=1;i<=n;i++){if(!st[i]){ok=true;dfs(i);ans+=ok;}}cout<<ans<<endl;return ;
}
F. Consecutive Subsequence
这一题是一个简单的dp记录方案我们考虑直接用map来存储,用pre表示上一个节点,idx当前位置,dp表示数量即可表示所有的信息从前完后的去找每一个数的x-1是否存在是一定合理的
void solve(){cin>>n;vector<int> a(n+5);map<int,int> dp,pre,idx;for(int i=1;i<=n;i++) cin>>a[i];int pos=1;for(int i=1;i<=n;i++){dp[a[i]]=1;idx[a[i]]=i;if(dp.count(a[i]-1)){pre[i]=idx[a[i]-1];dp[a[i]]=dp[a[i]-1]+1;if(dp[a[i]]>dp[a[pos]]) pos=i;}}vector<int> ans;ans.push_back(pos);while(pre[pos]!=0){ans.push_back(pre[pos]);pos=pre[pos];}cout<<ans.size()<<endl;reverse(ans.begin(),ans.end());for(auto&v:ans) cout<<v<<' ';cout<<endl;return ;
}