河北大学选拔赛补题
选拔赛补题
A.级数求和
思路:直接求和再去判断即可
B.P4702 取石子(很好的一道思维题)
思路:其实拿到的时候有点感觉但不多开始模拟,于是我就用 n = 1,a[1,2,3,4]一直开始模拟,我得出了看最后状态的结论,最后用每一次最后的状态推出每个人在奇偶状态的胜率,最后推得Alice在奇数状态下会win,Bob则在偶数状态下会win
#include<iostream>
using namespace std;
const int N = 1e7+10;
int a[N];
int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n,sum = 0;cin>>n;
    for(int i = 1;i <= n;i++)
    {
        int x;cin>>x;
        sum += x;//目的是计算总量
    }
     if(sum & 1)cout<<"Alice"<<'\n';
    else cout<<"Bob"<<'\n';
    return 0;
}
C.P8480 「HGOI-1」PMTD
思路:我服了这题要考虑范围,不开 long long 真的离谱了
就是不需要考虑减法和除法(因为会使得数据减小)考虑加法和乘法即可,小学都知道,乘一个比1小的数,新得的数会比原来的数更小;因此可以得出特判条件!!
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define ll long long
const int N = 1e7+10;
ll a[N];
int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    ll n,m;
    cin>>n>>m;
    for(ll i = 1;i <= n;i++)
    {
        cin>>a[i];
    }
    sort(a+1,a+1+n);
    while(m--)
    {
        if(a[n] <= 1)a[n] += 2;
        else a[n] *= 2;
    }
    cout<<a[n] - a[1]<<'\n';
    return 0;
}
D.P1150 Peter 的烟
思路:又是抽象的一题,我是用cnt和sum分别记录能换多少个和一共能得到多少个
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int main()
{
    int n,k,cnt = 0,sum = 0;
    cin>>n>>k;
    cnt = n;
    sum = n;
    while(cnt >= k)
    {
       cnt -= k;//能换多少个
       sum ++;//把换掉的重新累加上
       cnt ++;//继续累加换掉的瓶子
    }
    cout<<sum<<'\n';
    return 0;
}
前缀和和差分专题
A.T179367 爱与愁的心痛
思路:就是求区间段的和,用总体的和减去剩余未包含的和即可求出所要求的目标
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 3e3+10;
#define inf 0x3f3f3f3f
int a[N],P[N];
int main()
{
    int n,m,minn = inf;
    cin>>n>>m;
    for(int i = 1;i <= n;i++)
    {
        cin>>a[i];
    }
    for(int i = 1;i <= n;i++)
    {
        P[i] = P[i-1] + a[i];
    }
    for(int i = m;i <= n;i++)
    {
        minn = min(minn,P[i] - P[i-m]);
    }
    cout<<minn<<'\n';
    return 0;
}
B.最大の和
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int N = 1e5+10;
int a[N],Pre[N];
int main()
{
    int n,k,maxx = 0;
    cin>>n>>k;
    for(int i = 1;i <= n;i++)
    {
        cin>>a[i];
    }
    for(int i = 1;i <= n;i++)
    {
        Pre[i] = Pre[i-1] + a[i];
    }
    for(int i = k;i <= n;i++)//计算从 a[i-k+1] 到 a[i] 的和
    {
        //cin>>k;
        maxx = max(maxx,Pre[i]-Pre[i-k]);
    }
    cout<<maxx<<'\n';
    return 0;
}
C.P8772 [蓝桥杯 2022 省 A] 求和
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
using ll = long long;
const int N = 2e5+10;
ll a[N],Prefix[N];
int main()
{
    ll n,sum = 0;
    cin>>n;
    for(int i = 1;i <= n;i++)
    {
        cin>>a[i];
    }
    for(int i = 1;i <= n;i++)
    {
        Prefix[i] = Prefix[i-1] + a[i];
    }
    for(int i = 2;i <= n;i++)//i这里从2开始计算是因为用第二个例子去乘第一个前缀和
    {
        sum =sum + a[i] * Prefix[i-1]; 
    }
    cout<<sum<<'\n';
    return 0;
}
B4038 [GESP202409 三级] 平衡序列
trick:
1.flag特判的妙用
2.每一次判断都是独立的,需要每一次都初始化flag
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int N = 1e4 + 10;
int a[N], Prefix[N];
int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t, n;
    //bool flag = 0; 他需要进行重新初始化,每一次都是新的开始
    cin >> t;
    while (t--)
    {
        cin >> n;
        for (int i = 1; i <= n; i++)
        {
            cin >> a[i];
        }
        for (int i = 1; i <= n; i++)
        {
            Prefix[i] = Prefix[i - 1] + a[i];
        }
        bool flag = 0;
        for (int i = 1; i < n; i++)
        {
            if (Prefix[i] == Prefix[n] - Prefix[i])
            {
                flag = 1;
                break;
            }
        }
        if (flag)
        {
            cout << "Yes" << '\n';
        }
        else
        {
            cout << "No" << '\n';
        }
    }
    return 0;
}
P6568 [NOI Online #3 提高组] 水壶
trick:
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e6+10;
int a[N],Pre[N];
int main()
{
    int n,k,maxx = 0;
    cin>>n>>k;
    for(int i = 1;i <= n;i++)
    {
        cin>>a[i];
    }
    for(int i = 1;i <= n;i++)
    {
        Pre[i] = Pre[i-1] + a[i];
    }
    for(int i = k+1;i <= n;i++)
    {
        **maxx = max(maxx,Pre[i]-Pre[i-k-1]);**
    }
    cout<<maxx<<'\n';
    return 0;
}
本文来自博客园,作者:Alaso_shuang,转载请注明原文链接:https://www.cnblogs.com/Alaso687/p/18556604

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号