A题
- 思路
前面全填零
- 代码
void solve()
{
ll n,s;cin >> n >> s;
// cout<<1<<endl;
ll m = (n+1) / 2;
// cout<<2<<endl;
if(n==1){
cout<<s<<endl;return;
}
ll ans = (s) / (n-m+1);
// cout<<3<<endl;
ans = max (0*1ll,ans);
cout << ans << endl;
}
B题
- 思路
连续 0 的串会产生贡献 1
- 代码
void solve()
{
string s;cin>>s;
int cnt=0;
for(int i = 0 ;i < s.size() ;i ++){
if(s[i]=='0'){
cnt++;
while(s[i] == '0')
i ++;
}
}
cout<<min(2,cnt)<<endl;
}
C题
- 思路
仔细分析一下,就那么几种情况;用一个变量 case1,case0,记录前面是否存在
0 1
0 1
这样的情况。
因为
1
1这样的情况肯定是最后要尽量找 0 | 0.
0
0这样的情况肯定是最后要尽量找 1 | 1。因为这样的贡献才会更大。
还有一些细节要处理
- 代码
void solve()
{
int n;cin>>n;
string s1,s2;
cin>>s1>>s2;
int cnt = 0;
int case1 = 0,case0 = 0;
for(int i = 0;i < n;i ++){
if(s1[i] != s2[i]){
cnt+=case0;//归零之前要确定前面是否存在
0
0 这样的情况。
cnt+=2;case1 = case0 = 0;
}
else {
if(s1[i] == '0'){
if(case0 == 1){
cnt +=1;continue;
}
if(case1 == 1){
cnt +=2;
case0 = case1 = 0;continue;
}
if(case0 == 0&&case1 == 0){
case0 = 1;
}
}
if( s1[i] == '1'){
if(case0 == 1){
cnt +=2; case0 = case1 = 0;
continue;
}
if(case0 == 0 && case1 == 0){
case1 = 1;
}
}
}
}
cnt+=case0;
cout<<cnt<<endl;
}
D题
- 思路
因为要求视力低的位置靠前,所以无论哪个版本,都是已经确定了最终位置。
现在要考虑的是,如何处理视力相等的,尽量产生的贡献值最少。贪心地想,肯定是首先出现的要安排位置靠后,这样才不会对同等视力的产生贡献;其次,对于多个数值的,例如
4 2
50 50 50 50 3 50 50 50。
肯定是前面的 50 先填了,然后 3 再填上。
- 代码
void solve_test()
{
int n,m;cin>>n>>m;
vector<pair<int,int> >a(n*m);
for(int i=0;i<n*m;i++){
cin>>a[i].first;
a[i].second=i;
}
sort(a.begin(),a.end());
for(int i=0;i<n*m;i++){
a[i].second=-a[i].second;
}
int res=0;
for(int i=0;i<n;i++){
sort(a.begin()+m*i,a.begin()+(m*i+m));
for(int j=0;j<m;j++){
for(int k=0;k<j;k++){
if(a[i*m+k].second>a[i*m+j].second) res++;
}
}
}
cout<<res<<endl;
}
E题
- 思路
因为贪心的讲,把 bud 挂在 leaf 上就会减少 一个,所以肯定是一个 bud 挂在另一个 bud 的leaf 下面。假设有 k 个 bud ,那么就会有 n-k-1个 leaf 。会挂 k-1 个 bud,也就减少了 k-1 个 leaf。那么答案就是 n-k2-1。注意特判 root。如果 root 不是 bud ,那 答案就是 n-2k-1。否则答案就是 n-2*k。 - 代码
#include<bits/stdc++.h>
using namespace std;
vector<vector<int> > g;
vector<int> type;
void dfs(int v,int p)
{
bool leaves = false;
for(auto to : g[v]){
if(to == p) continue;
dfs(to,v);
if(type[to] == 1) leaves = true;
}
if(v != p){
if(!leaves) type[v] = 1;
else type[v] = 2;
}
}
int main()
{
int t;cin>>t;
while(t--){
int n;cin>>n;
g.assign(n,vector<int>());
type.assign(n,-1);
for(int i=0;i<n-1;i++){
int x,y;
cin>>x>>y;--x;--y;
g[x].push_back(y);
g[y].push_back(x);
}
type[0]=0;
dfs(0,0);
bool root_leaf = false;
for(auto v:g[0]){
if(type[v] == 1){
root_leaf = true;
}
}
int k=0;
for(int i=0;i<n;i++){
k+=(type[i]==2);
}
cout<<n-2*k-root_leaf<<endl;
}
}