【题目链接】点击打开链接

【写在前面】弱鸡只搞懂了4个稍微简单题的做法,后面两题就只能ORZ大佬们了!题解可以在Wannafly群里来看,写得很详细。我就直接写的做法了。然后给出一个B站q神的讲解视频,orz!讲题视频

【B CodeForces - 363D】解题方法:贪心 + 二分答案

【AC代码】

int b[maxn], p[maxn], n, m, a, ans;

int main()
{
    cin>>n>>m>>a;
    for(int i = 0; i < n; i++) cin>>b[i];
    for(int i = 0; i < m; i++) cin>>p[i];
    sort(b, b + n);
    sort(p, p + m);
    ans = 0;
    int l = 0, r = min(n + 1, m + 1);
    int cnt = 50;
    while(l <= r && cnt--)
    {
        int mid = (l + r) / 2;
        LL sum = 0;
        for(int i = 0; i < mid; i++){
            if(b[n - 1 - i] < p[mid - 1 - i]){
                sum += p[mid - 1 - i] - b[n - 1 - i];
            }
        }
        if(sum <= a){
            l = mid;
            ans = mid;
        }
        else{
            r = mid;
        }
    }
    if(ans == 0){
        printf("0 0\n");
    }
    else{
       LL xx;
        LL ans2 = 0;
        for(int i = 0; i < ans; i++){
            ans2 += p[i];
        }
        ans2 -= a;
        if(ans2 < 0) ans2 = 0;
        printf("%d %lld",ans, ans2);
    }
    return 0;
}

【C 】水题,模拟一下即可。

【AC代码】

int n, x;
int main()
{
    cin>>n;
    int a1 = 0, a2 = 0, a3 = 0;
    for(int i = 1; i <= n; i++){
        scanf("%d",&x);
        if(i%3 == 1) a1 += x;
        if(i%3 == 2) a2 += x;
        if(i%3 == 0) a3 += x;
    }
    if(a1 > a2 && a1 > a3) printf("chest\n");
    if(a2 > a1 && a2 > a3) printf("biceps\n");
    if(a3 > a1 && a3 > a2) printf("back\n");
}

【D】弄懂题意之后,可以很容易得出这个题的结论就是对原来数组差分然后匹配一下即可。

【AC代码】

int n, m;
int a[maxn], b[maxn], h[maxn], w[maxn], nex[maxn], ans;
void getfail(){
    nex[0] = nex[1] = 0;
    for(int i = 1; i < m; i++){
        int j = nex[i];
        while(j != 0 && b[j] != b[i]) j = nex[j];
        nex[i+1] = (b[i] == b[j]) ? j + 1: 0;
    }
}
void kmp()
{
    int j = 0;
    for(int i = 0; i < n; i++){
        while(j != 0 && b[j] != a[i]) j = nex[j];
        if(b[j] == a[i]) j++;
        if(j == m){
            ans++;
            j = nex[j];
        }
    }
}
int main()
{
    cin>>n>>m;
    for(int i = 0; i < n; i++) cin>>h[i];
    for(int i = 0; i < m; i++) cin>>w[i];
    for(int i = 0; i < n; i++){
        if(i >= 1) a[i-1] = h[i] - h[i-1];
    }
    for(int i = 0; i < m; i++){
        if(i >= 1) b[i-1] = w[i] - w[i-1];
    }
    n--, m--;
    if(m == 0){
        cout<<n+1<<endl;
    }
    else{
        ans = 0;
        getfail();
        kmp();
        cout<<ans<<endl;
    }
}

【F】看起来很吓人,实际上仔细思考就是线段求交,再深入思考,就可以转化成求起点和终点在直线两侧的点的个数了。

【AC代码】

LL x1, y1, x2, y2, a, b, c;

int main()
{
    int n;
    cin>>x1>>y1>>x2>>y2>>n;
    int ans = 0;
    for(int i = 0; i < n; i++){
        cin>>a>>b>>c;
        int f1, f2;
        if(a*x1 + b*y1 + c > 0) f1 = 1;
        else f1 = -1;
        if(a*x2 + b*y2 + c > 0) f2 = 1;
        else f2 = -1;
        if(f1*f2 < 0) ans++;
    }
    printf("%d\n",ans);
    return 0;
}