Codeforces_818

A.winners总数为(k+1)diplomas。

#include<bits/stdc++.h>
using namespace std;

long long n,k;

int main()
{
    ios::sync_with_stdio(0);
    cin >> n >> k;
    long long t = n/2/(k+1);
    cout << t << " " << t*k << " " << n-t*(1+k) << endl;
    return 0;
}
View Code

B.一步步确定每个a值,若冲突,则不存在。

#include<bits/stdc++.h>
using namespace std;

int n,m,a[105],ans[105] = {0};
map<int,int> used;

int main()
{
    ios::sync_with_stdio(0);
    cin >> n >> m;
    for(int i = 1;i <= m;i++)  cin >> a[i];
    for(int i = 2;i <= m;i++)
    {
        if(ans[a[i-1]])
        {
            if((a[i-1]+ans[a[i-1]]-1)%n+1 != a[i])
            {
                cout << -1 << endl;
                return 0;
            }
        }
        else
        {
            int t = a[i]-a[i-1];
            if(t <= 0)   t += n;
            if(used.count(t))
            {
                cout << -1 << endl;
                return 0;
            }
            ans[a[i-1]] = t;
            used[t] = 1;
        }
    }
    int now = 1;
    for(int i = 1;i <= n;i++)
    {
        if(ans[i])  cout << ans[i] << " ";
        else
        {
            while(used.count(now))  now++;
            cout << now << " ";
            used[now] = 1;
        }
    }
    return 0;
}
View Code

C.统计每个横坐标,纵坐标的4个方向的前缀后缀和,暴力比较每个沙发,注意减去自己。

#include<bits/stdc++.h>
using namespace std;

int d,n,m,ll,rr,tt,bb,x[100005],xx[100005],y[100005],yy[100005],l[100005] = {0},r[100005] = {0},t[100005] = {0},b[100005] = {0};

int main()
{
    ios::sync_with_stdio(0);
    cin >> d >> n >> m;
    for(int i = 1;i <= d;i++)
    {
        cin >> x[i] >> y[i] >> xx[i] >> yy[i];
        l[min(x[i],xx[i])]++;
        r[max(x[i],xx[i])]++;
        t[min(y[i],yy[i])]++;
        b[max(y[i],yy[i])]++;
    }
    cin >> ll >> rr >> tt >> bb;
    for(int i = 1;i <= max(n,m);i++)
    {
        l[i] += l[i-1];
        t[i] += t[i-1];
    }
    for(int i = max(n,m);i >= 1;i--)
    {
        r[i] += r[i+1];
        b[i] += b[i+1];
    }
    for(int i = 1;i <= d;i++)
    {
        int cntl = l[max(x[i],xx[i])-1];
        int cntr = r[min(x[i],xx[i])+1];
        int cntt = t[max(y[i],yy[i])-1];
        int cntb = b[min(y[i],yy[i])+1];
        if(x[i] != xx[i])
        {
            cntl--;
            cntr--;
        }
        else
        {
            cntt--;
            cntb--;
        }
        if(cntl == ll && cntr == rr && cntt == tt && cntb == bb)
        {
            cout << i << endl;
            return 0;
        }
    }
    cout << -1 << endl;
    return 0;
}
View Code

D.只要累加当前符合要求的颜色数量就可以了。

#include<bits/stdc++.h>
using namespace std;

int n,c,a[1000005] = {0};

int main()
{
    ios::sync_with_stdio(0);
    cin >> n >> c;
    for(int i = 1;i <= n;i++)
    {
        int x;
        cin >> x;
        if(a[x] >= a[c])   a[x]++;
    }
    for(int i = 1;i <= 1000000;i++)
    {
        if(a[i] >= a[c] && i != c)
        {
            cout << i << endl;
            return 0;
        }
    }
    cout << -1 << endl;
    return 0;
}
View Code

E.相乘整除一个数可以用相乘取模为0表示,从左往右找整除的一段,然后从右往左缩小这一段到最小,把两边的情况乘起来,因为一直重复这种操作会有重复的情况多计算了,所以每一次计算后更新首位置。

#include<bits/stdc++.h>
using namespace std;

int n,k,a[100005];

int main()
{
    ios::sync_with_stdio(0);
    cin >> n >> k;
    for(int i = 1;i <= n;i++)   cin >> a[i];
    int b = 0;
    long long now = 1,ans = 0;
    for(int r = 1;r <= n;r++)
    {
        now = now*a[r]%k;
        if(!now)
        {
            int l = r+1;
            long long t = 1;
            while(--l)
            {
                t = t*a[l]%k;
                if(!t) break;
                now = t;
            }
            ans += (long long)(n-r+1)*(l-b);
            b = l;
        }
    }
    cout << ans << endl;
    return 0;
}
View Code

F.n个点中,选k个组成一个连通图,其他n-k个连出去,因为n-k ≥ 连通图的边数,因此k个组成的连通图的边为

最后答案为,二分确定k的临界,把临界点两边的两个点都算一下。

#include<bits/stdc++.h>
using namespace std;

int q;
long long n;

int main()
{
    ios::sync_with_stdio(0);
    cin >> q;
    while(q--)
    {
        cin >> n;
        long long l = 0,r = n;
        while(l < r)
        {
            long long mid = (l+r+1)/2;
            if(n-mid < mid*(mid-1)/2)   r = mid-1;
            else    l = mid;
        }
        cout << max(n-l+l*(l-1)/2,n-(l+1)+n-(l+1)) << endl;
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zhurb/p/7228315.html