Educational Codeforces Round 32
C. Buggy Robot
题意
给一个长度为n的字符串,问你至少有一个字符要出现在这个字符串要都存在长度为k的子串,问k的最大值(n<=1000,字母全是小写)
分析
暴力枚举每一个字符的情况, 对每一个字符来看k的最小值为同一个字符之间的最远距离,注意特判一下第一个和最后一个即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }
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.
直接枚举几个位置不满足条件即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }
E. Maximum Subsequence
题意
给n个数,问取出任意个数,求出%m的最大值(n<=35,m,a[i] <= 1e9)
分析
石乐志的忘记每次都要%,wa了好几发
折半枚举,现将前n/2和后n/2分别枚举出所有情况,然后枚举前部分二分后一部分即可
时间复杂度(2^(n/2)*log(n))
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }
*F. Connecting Vertices
题意
分析
dp
G. Xor-MST
题意
给n个点,每个点都有一个值,每条边的权值为这条边所连的两个点的xor(^)值,求这n个点的最小生成树(n<=2e5,a[i] <= 2e30)
分析
要么优秀要么生锈