Educational Codeforces Round 32
http://codeforces.com/contest/888
A Local Extrema【水】
【题意】:计算极值点个数
【分析】:除了第一个最后一个外,遇到极值点ans++,包括极大和极小
【代码】:
#include<bits/stdc++.h> using namespace std; int main() { int n,a[1000+10]; int maxn,minn; maxn=minn=0; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; } for(int i=2;i<=n-1;i++) { if(a[i]>a[i+1]&&a[i]>a[i-1]) maxn++; if(a[i]<a[i+1]&&a[i]<a[i-1]) minn++; } cout<<minn+maxn<<endl; return 0; }
B Buggy Robot【模拟】
【题意】:机器人从(0,0)出发,有UDLR四种走法,分别代表上下左右的方向,最后回到(0,0),给你一段包含这些走法的序列,求最多有几个走法正确(即可以删去最少的操作使其能够回到原点)。
【分析】:记录下四个方向执行了几次,然后取相反方向的最小值乘2。我是这么想的,还特判了。最后被hack了···
【代码】:
#include<bits/stdc++.h> using namespace std; int main() { int n,min1,min2; int l,d,u,r; l=d=u=r=min1=min2=0; char a[110]; cin>>n; for(int i=0;i<n;i++) { cin>>a[i]; if(a[i]=='L') l++; else if(a[i]=='D') d++; else if(a[i]=='U') u++; else r++; } if(l&&(!r)){ printf("0\n"); return 0; } if(r&&(!l)){ printf("0\n"); return 0; } if(u&&(!d)){ printf("0\n"); return 0; } if(d&&(!u)){ printf("0\n"); return 0; } if(l&&r) min1=2*min(l,r); if(u&&d) min2=2*min(u,d); printf("%d\n",min1+min2); return 0; }
#include <bits/stdc++.h> using namespace std; int main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); int N,l=0,r=0,u=0,d=0; cin>>N; string s; cin>>s; for(int i=0;i<s.length();i++){ if(s[i]=='L')l++; if(s[i]=='R')r++; if(s[i]=='U')u++; if(s[i]=='D')d++; } cout<<2*(min(l,r)+min(u,d))<<endl; }
C K-Dominant Character【贪心】
【题意】:给一小写字母组成的字符串,找个长度最短的k。使得这些长度为k的子串必须包含了某同一个字符。
【分析】:记录下两个相同字符的最长距离,然后取这些距离的最小值。最小化最大值。
一个数组记录该字母上一次出现的位置
一个数组记录该字母相邻最大距离
如果没有重复出现的字符呢
设定在-1和len两个位置上和所以字母相同
(金牌讲师010):对于aab
有a这个位置的是
1 2
字符串长度是3
间距分别是
0-1 1
1-2 1
2-4 2
0和4是字符串的边界外
所以对于字符a就是2是最大间距
b只有3这个位置出现
0-3 3
3-4 1
所以b的最大间距是3
这题答案就是2
字符串的边界外也算进去?
因为
___x___x____x__
两边还有__
x是出现的位置
【代码】:
#include<bits/stdc++.h> using namespace std; const int inf = 0x3f3f3f3f; const long long INF = 0x3f3f3f3f3f3f3f3fLL; const double pi = acos(-1.0); const int maxn = 100000+10; const int mod = 1e9+7; char a[maxn]; int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n; scanf("%s",a+1); int len=strlen(a+1),ans=len; for (int i=0;i<128;i++){ int tmp=0; int pos=0; for (int j=1;j<=len;j++)if (a[j]==i)tmp=max(tmp,j-pos),pos=j; tmp=max(tmp,len+1-pos); ans=min(ans,tmp); } printf("%d\n",ans); return 0; }
A permutation p of size n is an array such that every integer from 1 to n occurs exactly once in this array.
Let's call a permutation an almost identity permutation iff there exist at least n - k indices i (1 ≤ i ≤ n) such that pi = i.
Your task is to count the number of almost identity permutations for given numbers n and k.
The first line contains two integers n and k (4 ≤ n ≤ 1000, 1 ≤ k ≤ 4).
Print the number of almost identity permutations for given n and k.
4 1
1
4 2
7
5 3
31
5 4
76
【题意】:一个长为n的排列,其中pi=i的位置大于等于n-k的排列方案数, 比如n=5 k=3让你求有多少个1 2 3 4 5的排列使得至少5-3=2个数字在“原位”
【分析】:公式是C(n,i)*D(i) (0<=i<=k),
【代码】:
By RoniKing, contest: Educational Codeforces Round 32, problem: (D) Almost Identity Permutations, Accepted, # #include <bits/stdc++.h> #define LL long long using namespace std; //const int mod=1e9+7; const int maxn=1e3+100; LL D[maxn], C[maxn][1005]; int p[1000+100]; void init() { D[0]=1; D[1]=0; for(int i=1;i<maxn;i++)//错排 D[i]=((i-1)*(D[i-1]+D[i-2])); int i; //for (p[0]=i=1;i<=200000;i++) p[i]=1ll*p[i-1]*i%mod; for (int i = 0; i < maxn; i++)//排列组合 { for (int j = 0; j <= min(105, i); j++) { if (j == 0) C[i][j] = 1; else C[i][j] = (C[i-1][j] + C[i-1][j-1]) ; } } } int main() { init(); int t; int n,k; cin>>n>>k; LL ans=1; for(LL i=1;i<=n;i++) ans = ans * i ; LL val=1; for(int i=1;i<=k;i++) val=(val + D[i]*C[n][i]) ; // cout<<ans<<endl; cout<<val<<endl; //cout<<(ans-val)<<endl; }
#include<bits/stdc++.h> using namespace std; int main() { long long n,k; cin>>n>>k; long long ans=1; if(k>=2) ans+=n*(n-1)/2; if(k>=3) ans+=n*(n-1)*(n-2)/3; if(k>=4) ans+=n*(n-1)*(n-2)*(n-3)*3/8; cout<<ans; return 0; }