码迷,mamicode.com
首页 > 其他好文 > 详细

CCPC 2017 网络赛

时间:2017-08-20 10:09:38      阅读:214      评论:0      收藏:0      [点我收藏+]

标签:bad   ios   决策   scanf   for   nbsp   bool   continue   cto   

1001.我们的想法是,先构造n个要删掉的点,然后不断给图加边,使得每条边的其中一个点在n个点之中。

我们要使n个点之外的点尽量多,并且每次删掉的点在n个点之外。

贪心的决策是,每次操作,前n个点的度和令外的最大度的点度数相同。

然后删掉这个点之后,之后的操作,剩余的点也满足这个要求。所以度数最大的点必定与n个点有边。

于是可以这样构造,增加n批点(i = 1~n),每次增加n/i个点的,每个增加的点连出i条边到n个点。

这样,n个点每次增加的最大度数不超过1。但每次删点的时候(按n~1批的顺序),每删一批点,n个点度数都保证小于等于其余最大的度数。

技术分享
#include<bits/stdc++.h>
using namespace std;

struct xxx
{
    int x,y;
    xxx(int a,int b):x(a),y(b){};
};
vector<xxx> ans;

int main()
{
    ios::sync_with_stdio(0);
    int n = 20,cnt = n;
    for(int i = 1;i <= n;i++)
    {
        int now = 0,t = n/i;
        for(int j = 1;j <= t;j++)
        {
            cnt++;
            for(int k = 1;k <= i;k++)   ans.push_back(xxx(++now,cnt));
        }
    }
    cout << cnt << " " << ans.size() << endl;
    for(int i = 0;i < ans.size();i++)   cout << ans[i].x << " " << ans[i].y << endl;
    cout << n << endl;
    for(int i = 1;i <= n;i++)   cout << i << endl;
    return 0;
}
View Code

1002.


1003.对原图和互补图bfs,找是否存在三元环,vector用short不会mle。

另外,根据Ramsey定理,n ≥ 6时,肯定存在三人互相认识或者三人互相不认识的情况。n < 6暴力判断即可。

技术分享
#include<bits/stdc++.h>
using namespace std;

int n;
bool a[3005][3005];

int main()
{
    ios::sync_with_stdio(0);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(a,0,sizeof(a));
        scanf("%d",&n);
        for(int i = 1;i < n;i++)
        {
            for(int j = i+1;j <= n;j++) scanf("%d",&a[i][j]);
        }
        if(n >= 6)
        {
            printf("Bad Team!\n");
            continue;
        }
        else
        {
            int ok = 0;
            for(int i = 1;i <= n;i++)
            {
                for(int j = i+1;j <= n;j++)
                {
                    for(int k = j+1;k <= n;k++)
                    {
                        if(a[i][j] == 1 && a[i][k] == 1 && a[j][k] == 1)    ok = 1;
                        if(a[i][j] == 0 && a[i][k] == 0 && a[j][k] == 0)    ok = 1;
                    }
                }
            }
            if(ok)  printf("Bad Team!\n");
            else    printf("Great Team!\n");
        }
    }
    return 0;
}
View Code

1004.先把两个串reverse,然后跑kmp,统计每个数量的个数,注意最后一部分长度要加回来。

技术分享
#include<bits/stdc++.h>
#define MOD 1000000007
using namespace std;

char s1[1000005],s2[1000005];
int cnt[1000005],ne[1000005];

void getnext1(char *s)
{
    int i = 0,j = -1,len = strlen(s);
    ne[0] = -1;
    while(i < len)
    {
        if(j == -1 || s[i] == s[j]) ne[++i] = ++j;
        else    j = ne[j];
    }
}

void kmp(char *x,char *y)
{
    getnext1(x);
    int i = 0,j = 0,leny = strlen(y),lenx = strlen(x);
    while(i < leny)
    {
        if(j == -1 || x[j] == y[i])
        {
            i++,j++;
            if(j > 0)   cnt[j]++;
            if(j == lenx)   j = ne[j];
        }
        else
        {
            j = ne[j];
            if(j > 0)   cnt[j]++;
        }
    }
}

int main()
{
    ios::sync_with_stdio(0);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s%s",s1,s2);
        int len1 = strlen(s1),len2 = strlen(s2);
        reverse(s1,s1+len1);
        reverse(s2,s2+len2);
        memset(cnt,0,sizeof(cnt));
        kmp(s2,s1);
        long long ans = 0;
        for(int i = len2;i >= 1;i--)
        {
            ans = (ans+(long long)cnt[i]*i)%MOD;
            cnt[ne[i]] += cnt[i];
        }
        printf("%lld\n",ans);
    }
    return 0;
}
View Code

1005.n条边的最大面积计算分4种情况。二分答案,判断。

技术分享
#include<bits/stdc++.h>
using namespace std;

int n;

long long f(long long x)
{
    long long t = x/4;
    if(x%4 == 0)    return t*t*2;
    if(x%4 == 1)    return t*t*2+(t+t-1)/2;
    if(x%4 == 2)    return 2*t*(t+1);
    return 2*t*(t+1)+(t+t+1)/2;
}

int main()
{
    ios::sync_with_stdio(0);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        long long l = 4,r = 1e8;
        while(l < r)
        {
            long long mid = (l+r)/2;
            if(f(mid) >= n) r = mid;
            else    l =  mid+1;
        }
        printf("%lld\n",l);
    }
    return 0;
}
View Code

1006.


1007.计算k进制1~n累计回文个数,在最高位之前的那些位没有限制,比较好算,最高位注意减一的情况。

技术分享
#include<bits/stdc++.h>
using namespace std;

int l,r,x,y,a[105];

long long f(int n,int k)
{
    int cnt = 0;
    long long x = n;
    while(x)
    {
        a[++cnt] = x%k;
        x /= k;
    }
    if(cnt == 0)    return 0;
    long long ans = 0,now = 1;
    for(int i = 1;i < cnt;i += 2)
    {
        now *= k;
        ans += now-now/k;
        if(i+1 < cnt)   ans += now-now/k;
    }
    long long t1 = 0;
    now = 1;
    for(int i = cnt;i > cnt/2;i--)
    {
        t1 = t1*k+a[i];
        now *= k;
    }
    long long t2 = t1;
    int i = cnt%2?cnt/2+2:cnt/2+1;
    for(;i <= cnt;i++)  t2 = t2*k+a[i];
    if(t2 > n)  ans += t1-now/k;
    else    ans += t1-now/k+1;
    return ans;
}

int main()
{
    ios::sync_with_stdio(0);
    int T;
    scanf("%d",&T);
    int z = 0;
    while(T--)
    {
        scanf("%d%d%d%d",&l,&r,&x,&y);
        long long ans = 0;
        for(int i = x;i <= y;i++)
        {
            ans += f(r,i)*(i-1)+r;
            ans -= f(l-1,i)*(i-1)+l-1;
        }
        printf("Case #%d: %lld\n",++z,ans);
    }
    return 0;
}
View Code

 

CCPC 2017 网络赛

标签:bad   ios   决策   scanf   for   nbsp   bool   continue   cto   

原文地址:http://www.cnblogs.com/zhurb/p/7398527.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!