Codeforces Round #424 Div. 2专题

来源:互联网 发布:离子注入仿真软件 编辑:程序博客网 时间:2024/06/09 19:03

A题:波峰的时候可以连续相等否则其他不行。然后满足只有一个波峰或者单调就行了。


代码:

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;const int mx = 1e2+10;int n,m,a[mx];int main(){while(~scanf("%d",&n)){int pos = 0,max = 0;for(int i =1;i<=n;i++){scanf("%d",a+i);if(a[i]>max){max = a[i];pos = i;}}for(int i=1;i<pos;i++){if(a[i]>a[i+1]||(a[i]==a[i+1]&&a[i]!=max)){puts("NO");return 0;}}for(int i=n;i>pos;i--){if(a[i]>a[i-1]||(a[i]==a[i+1]&&a[i]!=max)){puts("NO");return 0;}}puts("YES");}    return 0;}

B:给你两个键盘模式叫你互换就换一下26个字母就行了

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;const int mx = 1e2+10;int n,m,a[mx];int id[26];char c1[40],c2[40],c3[1100];int main(){while(~scanf("%s%s",c1,c2)){for(int i=0;i<26;i++)id[c1[i]-'a']=i;scanf("%s",c3);int len =strlen(c3);for(int i=0;i<len;i++){if(isdigit(c3[i]))  putchar(c3[i]);else if(isupper(c3[i])) putchar(c2[id[c3[i]+32-'a']]-32);else putchar(c2[id[c3[i]-'a']]);}puts("");}    return 0;}
C:将连续序列和的数组排序,将最小的b[i]枚举到每个位置,然后看b2-bn的数是否都能找到相应的位置。

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string> #include <math.h>#include <stdlib.h>#include <time.h>using namespace std;const int mx = 2e3+10;int n,m,a[mx],sum[mx],b[mx],cnt[mx];int main(){sum[0] = 0;while(~scanf("%d%d",&n,&m)){for(int i=1;i<=n;i++){scanf("%d",a+i);sum[i]=sum[i-1]+a[i];cnt[i] = sum[i];}for(int i=1;i<=m;i++) scanf("%d",b+i);sort(b+1,b+1+m);sort(cnt+1,cnt+1+n);int ans = 0,t=2;sum[1]  = cnt[1]; for(int i=2;i<=n;i++)if(cnt[i-1]!=cnt[i]) sum[t++] = cnt[i];for(int i=1;i<t;i++){int flag=0,j = 2;while(j<=m){int po = b[j]-b[1]+sum[i];int pos = lower_bound(cnt+1,cnt+1+n,po)-cnt;if(pos==n+1||cnt[pos]!=po){flag = 1;break;}j++;}if(!flag) ans++;}printf("%d\n",ans);}    return 0;}
D:dp,贪心,二分都可以做。这里满足决策单调性直接贪心比较简单一点

 #include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string> #include <math.h>#include <stdlib.h>#include <time.h>using namespace std;typedef long long ll;const int mx = 2e3+10;int n,m,q,a[mx],b[mx];int sum[mx];ll dis(int x,int y){ return abs(1ll*b[x]-1ll*a[y])+abs(1ll*b[x]-1ll*q);  }int main(){while(~scanf("%d%d%d",&n,&m,&q)){ll ans = 1e16;memset(sum,0,sizeof(sum));for(int i=1;i<=n;i++) scanf("%d",a+i);for(int i=1;i<=m;i++) scanf("%d",b+i);sort(a+1,a+1+n);sort(b+1,b+1+m);for(int i=1;i<=m-n+1;i++){ll cnt = 0;for(int j=1;j<=n;j++){cnt = max(cnt,dis(i+j-1,j));}ans = min(cnt,ans);}cout << ans <<endl;}    return 0;}
E:将牌的排名从小到大枚举。假设排名i的值在牌堆最底下的位置是k那么当处理i+1的时牌堆状态应该是k-n加上1-(k-1)拼接而成。那么我接下来只需要去找在1-(k-1)中

排名i+1最底层的,如果找不到则在k-n中找。然后树状数组更新被删过的点就行了

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string> #include <math.h>using namespace std;typedef long long ll;const int mx = 1e5+10;int n,m,q,minn = 1e9;vector<int> vec[mx];ll sum[mx];inline int lowbit(int x) { return x&(-x); }void add(int x,int v){  for(int i=x;i<=n;i+=lowbit(i))  sum[i]+=v;  }ll getsum(int x){ll ans = 0;while(x){ans += sum[x];x -= lowbit(x);}return ans;}int main(){while(~scanf("%d",&n)){memset(sum,0,sizeof(sum));for(int i=1;i<=n;i++) scanf("%d",&q), vec[q].push_back(i), add(i,1), minn = min(q,minn);ll ans = getsum(vec[minn].back()),k = vec[minn].back();for(int j=0;j<vec[minn].size();j++) add(vec[minn][j],-1);for(int i=minn+1;i<mx;i++){if(!vec[i].size()) continue;auto it = lower_bound(vec[i].begin(),vec[i].end(),k);if(it == vec[i].begin()) ans += getsum(*(it = --vec[i].end()))-getsum(k-1);else  ans += getsum(*(--it))+getsum(n)-getsum(k-1);k = *it;for(int j=0;j<vec[i].size();j++) add(vec[i][j],-1); }cout << ans <<endl;}    return 0;}
F:数学题。通过计算可得(C(所以的竹子限定长度和)+k)/SUM(每个竹子在某一天中没砍掉的天数和)>=d,那么我只需枚举i∈1-sqrt(C+k)还有(C+k)/i就行了多了也是重复,在这面找答案就行了。





原创粉丝点击