C. Dessert Café:
題意: 給你一個N個節點的樹,樹上有m個房子,問樹上有幾個節點是在兩個房子之間的。
思路:我們發現只要是該節點的子樹里包括了所有節點或者只有一個節點,那么這個結點肯定不是在兩個房子之間的,至於證明我們可以畫幾幅圖證明。代碼實現的話,需要用到num[]數組記錄該節點子樹里房子個數,然后dfs一邊即可。
代碼:
int n,k; vector<int>mp[maxn]; int num[maxn]; bool isA[maxn]; int ans=0; void dfs(int u,int f) { int cnt=0; for(int i=0;i<mp[u].size();i++) { int v=mp[u][i]; if(v!=f) { dfs(v,u); num[u]+=num[v]; if(num[v]) cnt++; } } if(num[u]!=k) cnt++; //dbg(u); if(cnt>=2&&!isA[u]) ans++; //dbg(ans); } void run() { n=rd(); k=rd(); for(int i =1;i<n;i++) { int u=rd(),v=rd(),w=rd(); mp[u].push_back(v); mp[v].push_back(u); } for(int i=0;i<k;i++) { int x=rd(); num[x]=1; isA[x]=true; ans++; //cout<<ans<<" sss"<<endl; } dfs(1,-1); cout<<ans<<endl; } signed main() { run(); return 0; }
E - Imprecise Computer
思路:通過分析不難發現如果前面產生了1>2的錯誤判斷,那么這個錯誤會一直影響到最后,然后我們只要在產生這樣錯誤后對后面的d +1或者-1 直到最后消除影響,那么就可以構造成功,而且中途是不能出現d>=2 的情況。
代碼實現:
int n; int d[maxn]; void run() { n=rd(); for(int i=1;i<=n;i++) d[i]=rd(); bool flag=true; for(int i=1;i<=n;i++) { if(d[i]>1) { puts("NO"); return ; }else if(d[i]) { if(d[i+1]) d[i+1]--; else d[i+1]--; } } puts(d[n]==0?"YES":"NO"); } signed main() { // int t=rd(); // while(t--) run(); return 0; }