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; }