Codeforces Round #831 (Div. 1 + Div. 2)
Dashboard - Codeforces Round #831 (Div. 1 + Div. 2) - Codeforces
A. Factorise N+M
题解:奇数加3,偶数加2凑成偶数
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll,ll> pll; const ll N=2e5+10; const ll inf=1e18; const ll mod=9901; signed main(){ ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); ll t;cin>>t; while(t--){ ll n;cin>>n; if(n&1) cout<<3<<endl; else cout<<2<<endl; } }
B. Jumbo Extra Cheese 2
题解:每一条边,如果把它放在平行于X轴那么最后一定会直接加到周长里,所以把长的边竖放,这样只会取到最长边
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll,ll> pll; const ll N=2e5+10; const ll inf=1e18; const ll mod=9901; pll a[N]; signed main(){ ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); ll t;cin>>t; while(t--){ ll n;cin>>n; ll maxn=-inf; ll lx=0; for(ll i=1;i<=n;i++){ cin>>a[i].first>>a[i].second; maxn=max(maxn,a[i].first); maxn=max(maxn,a[i].second); lx+=min(a[i].first,a[i].second); } cout<<(lx+maxn)*2<<endl; } }
C. Bricks and Bags
题解: 将第一个点固定为a[1],然后将剩下的点分为两堆,[2 - i-1] [i - n],然后分别放在第二个和第三个的位置,这个时候的最小值就是 a[i]-a[1]+a[i]-a[i-1],然后枚举i找出最大值,然后反向跑一遍查看是否有更大的。
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll,ll> pll; const ll N=2e5+10; const ll inf=1e18; const ll mod=9901; ll a[N]; signed main(){ ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); ll t;cin>>t; while(t--){ ll n;cin>>n; for(ll i=1;i<=n;i++) cin>>a[i]; sort(a+1,a+1+n); ll ans=-inf; for(ll i=1;i<n;i++) ans=max(ans,a[n]-a[i]+a[i+1]-a[i]); for(ll i=n;i>1;i--) ans=max(ans,a[i]-a[1]+a[i]-a[i-1]); cout<<ans<<endl; } }
D. Knowledge Cards
题解:可以理解不管(1,1)和(n,m)的数字华容道,所以每次当前的棋子能走到(n,m)就说明一定最少有一个空的位置。
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll,ll> pll; const ll N=2e5+10; const ll inf=1e18; const ll mod=9901; ll a[N]; signed main(){ ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); ll t;cin>>t; while(t--){ ll n,m,k;cin>>n>>m>>k; for(ll i=1;i<=k;i++) cin>>a[i]; ll sum=0,beg=k; bool flag=0; priority_queue<ll> q; for(ll i=1;i<=k;i++){ q.push(a[i]);sum++; if(sum>=n*m-2) flag=1;//判断是否合法 while(q.size()&&q.top()==beg){ q.pop();beg--;sum--; } } cout<<(flag?"TIDAK":"YA")<<endl; } }
E. Hanging Hearts
题解:这颗树是从叶子节点开始向上操作,所以最大的时候肯定是靠下的节点值小,上面的节点值大,但是如果一个节点有多个叶子节点,那么如果将这些叶子节点一次加入,那么根节点一定小于等于这些叶子节点,所以最大值就是判断选这些叶子节点不选根节点,和选根节点不选叶子节点这两种情况。
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll,ll> pll; const ll N=2e5+10; const ll inf=1e18; const ll mod=9901; ll a[N],sum[N],ans[N],len[N]; vector<ll> son[N]; void dfs(ll x){ if(!son[x].size()){ ans[x]=len[x]=1; return ; } for(auto it:son[x]){ dfs(it); ans[x]+=ans[it];//选子节点 len[x]=max(len[x],len[it]+1);//选根节点 } ans[x]=max(ans[x],len[x]);//求最大值 } signed main(){ ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); ll n;cin>>n; for(ll i=2;i<=n;i++){//记录子节点 cin>>a[i];son[a[i]].push_back(i); } dfs(1); cout<<ans[1]; }