Educational Codeforces Round 32

C. Buggy Robot

题意

给一个长度为n的字符串,问你至少有一个字符要出现在这个字符串要都存在长度为k的子串,问k的最大值(n<=1000,字母全是小写)

分析

暴力枚举每一个字符的情况, 对每一个字符来看k的最小值为同一个字符之间的最远距离,注意特判一下第一个和最后一个即可

 

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5+5;

char s[maxn];

int main()
{
    scanf("%s", s+1);
    int len = strlen(s+1);
    int minx = len;
    for(int i = 0; i < 26; i++)
    {
        int pos = 0;
        int ans = 0;
        for(int j = 1; j <= len; j++)
        {
            if((s[j]-'a') == i)
            {
                 ans = max(ans, j-pos);
                 pos=j;
            }
        }
        ans = max(len-pos+1,ans);
        minx = min(minx, ans);
    }
    printf("%d\n", minx);
    return 0;
}
View Code

 


 D. Almost Identity Permutations

题意

 给n个数,其中有k个数可以pi != i,问可能的排列数的种类 (4 ≤ n ≤ 1000, 1 ≤ k ≤ 4)

分析

错排和组合数

错排公式:D(n) = (n-1)* [ D(n-2) + D(n-1) ]   , 特殊地,D(1) = 0, D(2) = 1.

直接枚举几个位置不满足条件即可
#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int maxn = 1e5 + 10;


int main()
{
    ll sum = 0;
    ll n, k;
    scanf("%lld%lld", &n ,&k);
    if(k>=4) sum += ((n*(n-1)*(n-2)*(n-3))/24)*9;
    if(k>=3) sum += ((n*(n-1)*(n-2))/6)*2;
    if(k>=2) sum += ((n*(n-1))/2);
    if(k>=1) sum += 1;
    printf("%lld\n", sum);
    return 0;
}
View Code

 


 E. Maximum Subsequence

题意

给n个数,问取出任意个数,求出%m的最大值(n<=35,m,a[i] <= 1e9)

分析

石乐志的忘记每次都要%,wa了好几发

折半枚举,现将前n/2和后n/2分别枚举出所有情况,然后枚举前部分二分后一部分即可

时间复杂度(2^(n/2)*log(n)) 

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

const int maxn = 1e6 + 5;

int a[40],n,m;
int num1[maxn],num2[maxn];

int main()
{
     scanf("%d%d", &n, &m);
     for(int i = 0; i < n; i++)
     {
         scanf("%d", &a[i]);
         a[i]%=m;
     }
     int n1 = n/2, n2 = n-n1;
     int ans1 = 0, ans2 =0;
     for(int i = 0; i < (1<<n1); i++)
     {
         int temp = 0;
         for(int j = 0; j < n1; j++)
         {
             if(i & (1<<j))
                temp += a[j],temp%=m;
         }
         temp%=m;
         num1[ans1++]=temp;
     }
     int k = 0;
     for(int i = n1; i <= n1+n2-1; i++)
     {
         a[k++]=a[i];
     }
     for(int i = 0; i < (1<<n2); i++)
     {
         int temp=0;
         for(int j = 0; j < n2; j++)
         {
             if(i & (1<<j))
            {
                temp += a[j];
                temp%=m;
            }
         }
         temp%=m;
         num2[ans2++]=temp;
     }
     sort(num1,num1+ans1);
     sort(num2,num2+ans2);
     int maxx = max(num1[ans1-1], num2[ans2-1]);
     for(int i = 0; i < ans1; i++)
     {
         int p = upper_bound(num2,num2+ans2,m-1-num1[i])-num2-1;
         int temp = num1[i]+num2[p];
         maxx = max(temp, maxx);
     }
     printf("%d\n", maxx);
     return 0;
}
View Code

 


*F. Connecting Vertices

题意

分析

dp


G. Xor-MST

题意

给n个点,每个点都有一个值,每条边的权值为这条边所连的两个点的xor(^)值,求这n个点的最小生成树(n<=2e5,a[i] <= 2e30)

分析

 

posted @ 2017-11-21 23:59  Superwalker  阅读(178)  评论(0编辑  收藏  举报