每次都是前40分钟签到,后面基本都在摸鱼了.......
A题
思路:有点div2A题的味道,起始思路很明显,我们观察1412,他是有四个部分组成的,也就是对于给定的1,2,4的个数,我们如何进行分配,使得他的子序列的情况最多。至于一定要找规律的话,建议从少的开始找起,然后大概就能发现规律了。我们发现,对于这些位置我们采用111...144444...44111...111222222这样的方法来分最好,结果就是连续的个数的乘积就是了,但是对于1的两个位置来说,我们要尽量采用平均分法就行了。
还有就是,不开longlong见祖宗。
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; void solve(){ int n,m,k; cin>>n>>m>>k; ll l=n/2,r=n-l; ll ans=l*r*m*k; cout<<ans<<endl; } int main(){ int t; cin>>t; while(t--){ solve(); } return 0; }
B题
一开始看到题目,以为要用到关于树这方面的知识点(orz,还不怎么会树的题目),但发现过的人挺多的,就冷静下来思考了一下,然后纸上进行了模拟,才发现其实不要用到树的知识,用用容器也是可以做的。总之,就是遇到题目现不要先入为主,冷静思考,说不定你就会有独到的想法。
思路:我们发现对于每个点,都要输出离它距离为2的点的个数,然后这n个点又一定是相连的。这样,我们就可以对每个点开vector保存与它相连的点的编号(这个过程在输入是可以进行)。然后,我们在遍历从1-n的每个编号i,对于每个i然后我们对相应的vector[i]进行遍历,我们在这个vector里面找到与i相连的每个编号j,然后如果这个编号j对应的vector里面的元素超过一个(也就是与j相连的点超过1),那么就存在至少一个与i相距为2的点(为什么个数大于1,因为每个j,j里面的vector一定存在i,所以至少有一个元素),这个建议纸上模拟一下更好。
举个例子吧,你只有一个朋友小明,小明除你之外的朋友还有几个就是你这个点的ans,那么你就要知道小明的朋友有几个,然后减去你这个朋友就行了,如果你有多个朋友也同样这样算。
代码:
#include<bits/stdc++.h> using namespace std; vector<int> a[200010]; int main(){ int n; cin>>n; int u,v; for(int i=1;i<n;i++){ cin>>u>>v; a[u].push_back(v); a[v].push_back(u); } for(int i=1;i<=n;i++){ vector<int>::iterator it=a[i].begin(); int ans=0; for(;it!=a[i].end();it++){ if(a[*it].size()>1) ans+=a[*it].size()-1; } cout<<ans<<endl; } return 0; }