zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 62 (Rated for Div. 2)

    A. Detective Book

    题意:一个人读书  给出每一章埋的坑在第几页可以填完 。 一个人一天如果不填完坑他就会一直看 问几天能把这本书看完

    思路:模拟一下 取一下过程中最大的坑的页数  如果最大页数等于当前页数 day++即可

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define FOR(i,f_start,f_end) for(int i=f_start ;i<=f_end;i++)
     4 #define MT(x,i) memset(x,i,sizeof(x))
     5 #define inf 0x3f3f3f3f
     6 #define mkp make_pair
     7 #define all(v) (v).begin(),(v).end()
     8 #define F first
     9 #define S second
    10 #define pii pair<int,int>
    11 #define pb push_back
    12 const int maxn=65000+5;
    13 int a[maxn];
    14 int main(){
    15     int n,k;
    16     scanf("%d",&n);
    17     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    18     int p=1,maxnum=0;
    19     int cnt=0;
    20     while(p<=n){
    21         if(a[p]>=maxnum){
    22             maxnum=a[p];
    23         }
    24          if(p==maxnum){
    25             cnt++;
    26             maxnum=0;
    27         }
    28         p++;
    29     }
    30     cout<<cnt<<endl;
    31     return 0;
    32 }
    View Code

    B. Good String

    题意:给出只含 >  <的字符串  >可以免费把右边的字符删掉  <可以免费把左边的字符删掉  越界就什么都没变化  问不免费删几次可以把该字符串全部变成一种字符

    思路: 如果s[0]='>'或者s[n]='<'都是可以直接把一边全部免费删掉的   如果不是这两种情况 那么就找  从左边开始 和s[n] 相等  的最小位置   和从右边开始和s[1]相等的最小位置 哪个小输出哪个

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define FOR(i,f_start,f_end) for(int i=f_start ;i<=f_end;i++)
     4 #define MT(x,i) memset(x,i,sizeof(x))
     5 #define inf 0x3f3f3f3f
     6 #define mkp make_pair
     7 #define all(v) (v).begin(),(v).end()
     8 #define F first
     9 #define S second
    10 #define pii pair<int,int>
    11 #define pb push_back
    12 const int maxn=65000+5;
    13 char  s[maxn];
    14 int main(){
    15     int t;
    16     int n;
    17     scanf("%d",&t);
    18     while(t--){
    19         scanf("%d",&n);
    20         scanf("%s",s+1);
    21         if(s[1]!=s[n]){
    22             if(s[1]=='<'){
    23                 int ans=0;
    24                 for(int i=n;i>=1;i--){
    25                     if(s[i]=='<'){
    26                         ans=n-i;break;
    27                     }
    28                 }
    29                 for(int i=1;i<=n;i++){
    30                     if(s[i]=='>'){
    31                         ans=min(i-1,ans);
    32                         break;
    33                     }
    34                 }
    35                 cout<<ans<<endl;
    36             }
    37             else if(s[1]=='>'){
    38                 cout<<0<<endl;
    39             }
    40 
    41         }
    42         else {
    43             cout<<0<<endl;
    44         }
    45         
    46                 
    47     }
    48     return 0;
    49 }
    View Code

    C. Playlist

    题意 给出n个pair 和k  可以选k个以内的Pair  问最大的  min(first)*(sigma(second))是多少

    思路“:直接优先队列升序存second 然后按first 降序排列 n个pair 从最大的Pair开始枚举 每次进优先队列 如果队列超过k 就把 second小的出队即可 

    比赛的时候想复杂了 想成了还要删除一个点  不知道怎么处理重复  其实删除也可以写 用multiset删除的时候只要删除find回的那个位置的值就不会把相同的全部删掉了

     1 #include<bits/stdc++.h>
     2 #define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;i++)
     3 #define MS(arr,arr_value) memset(arr,arr_value,sizeof(arr)) 
     4 #define F first 
     5 #define S second
     6 #define pii pair<long long  ,long long  >
     7 #define mkp make_pair
     8 #define pb push_back
     9 using namespace std;
    10 typedef long long ll;
    11 const int maxn=5e6+4;
    12 priority_queue<int,vector<int>,greater<int> >q;
    13 pii a[maxn];
    14 bool  cmp(pii a,pii b){
    15 return a.S>b.S;
    16 }
    17 int main(){
    18     int n,k;
    19     scanf("%d%d",&n,&k);
    20     int x,y;
    21     for(int i=1;i<=n;i++){
    22         scanf("%d%d",&x,&y);
    23        a[i].F=x;a[i].S=y;
    24     }
    25     sort(a+1,a+1+n,cmp);
    26     q.push(a[1].F);
    27     long long sum=a[1].F;
    28     long long ans=1ll*a[1].F*a[1].S;
    29     for(int i=2;i<=n;i++)
    30     {
    31         q.push({a[i].F});
    32         sum+=a[i].F;
    33         while(q.size()>k){sum-=q.top();q.pop();}
    34         ans=max(ans,sum*a[i].S);
    35     }
    36     cout<<ans<<endl;
    37 
    38 
    39     return 0;
    40 }
    View Code

    D. Minimum Triangulation

    题意:给出正n边形 分解成很多个不相交的三角形 并且不相交全覆盖正n边形  n边形角编号逆时针 1--n  三角形的权值为三个角编号乘积 问所有三角形最小乘积和是多少

    思路:面向样例编程 每个三角形都从1点出发即可(不会证)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define FOR(i,f_start,f_end) for(int i=f_start ;i<=f_end;i++)
     4 #define MT(x,i) memset(x,i,sizeof(x))
     5 #define inf 0x3f3f3f3f
     6 #define mkp make_pair
     7 #define all(v) (v).begin(),(v).end()
     8 #define F first
     9 #define S second
    10 #define pii pair<int,int>
    11 #define pb push_back
    12 const int maxn=65000+5;
    13 char  s[maxn];
    14 int main(){
    15     int n,k;
    16     scanf("%d",&n);
    17     long long ans=0;
    18     for(int i=2;i<=n-1;i++){
    19         ans+=1ll*i*(i+1);
    20     }
    21     cout<<ans<<endl;
    22 
    23     return 0;
    24 }
    View Code

    E. Palindrome-less Arrays

    题意:给定一串数字  不确定的地方用-1 表示 确定的就有确切的数字  不能有大于1的奇回文串 问在-1的地方填数字  可以填1---k 有多少种填法

    思路 :由不能有大于1的奇回文串 等价于 奇数序号的数字相邻不能相等 偶数序号的数字相邻不能相等 分解出来即可、

    然后进行状态定义 dp[i][0/1]  表示i位置和下一个确定数字的数字相同的填法(第二维是1)  和不同的填法(第二维是0)

    需要特殊处理开始和结尾 即 :- 1 -1 -1 -1 A      A表示已经确定的数字  开头的可能性为pow(k-1,有多少个1) 结尾类似

    其余的确定数字之前的段可以提取出来分段dp 乘法原理乘起来即可

    中间转移为 dp[i][1]=dp[i-1][0]

          dp[i][0]=dp[i-1][0]*(k-2)+dp[i-1][1]*(k-1) 

    这里其实就是分类讨论的思想 如果dp只有一维的话那么后面的数字就会影响前面 产生后效性 

    那么怎么取消这种后效性呢?那就是对后面的数字进行分类讨论 相当于已经确定了后面的数字 

    所以前面填数字的时候就可以根据分类讨论的类别来进行转移 就可以取消后效性了

     1 #include<bits/stdc++.h>
     2 #define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;i++)
     3 #define MS(arr,arr_value) memset(arr,arr_value,sizeof(arr)) 
     4 #define F first 
     5 #define S second
     6 #define pii pair<long long  ,long long  >
     7 #define mkp make_pair
     8 #define pb push_back
     9 using namespace std;
    10 typedef long long ll;
    11 const int maxn=2e5+5;
    12 const ll mod=998244353;
    13 long long  a[maxn];
    14 long long  dp[maxn][2];
    15 ll n,k;
    16 vector<ll>even,odd;
    17 vector<ll>even_div,odd_div;
    18 long long solve(const vector<ll>&a,const vector<ll>&div,int flag){
    19     long long ans=1;
    20     if(div.size()==0){
    21         ans=k;
    22         ans%=mod;
    23         for(int i=1;i<a.size();i++){
    24             ans*=(k-1);
    25             ans%=mod;
    26         }
    27         return ans;
    28     }
    29     if(div[0]!=0){
    30         for(int i=0;i<div[0];i++){
    31             ans*=(k-1);
    32             ans%=mod;
    33         }
    34     }
    35     MS(dp,0);
    36     for(int z=0;z<div.size()-1;z++){
    37         //cout<<a[div[z]]<<" what ?  "<<a[div[z+1]]<<endl;
    38         if(a[div[z]]!=a[div[z+1]]){
    39             dp[div[z]][1]=0;
    40             dp[div[z]][0]=1;
    41         }
    42         else dp[div[z]][1]=1,dp[div[z]][0]=0;
    43     }
    44     for(int z=1;z<div.size();z++){
    45         //int zz=0;
    46         if(a[div[z-1]]!=a[div[z]])dp[div[z-1]][0]=1;
    47         for(int i=div[z-1]+1;i<div[z];i++){
    48     //        zz=1;
    49             //if(i!=div[z]-1)dp[i][0]=(((dp[i-1][1]+dp[i-1][0])%mod)*(k-1)%mod);
    50              dp[i][0]=(((dp[i-1][0]*(k-2)%mod)+(dp[i-1][1]*(k-1)%mod))%mod);
    51     //        cout<<i<<" ?? "<<dp[i-1][0]<<" fuck "<<dp[i-1][1]<<endl;
    52             dp[i][1]=dp[i-1][0]%mod;
    53             
    54         }
    55         ans=((ans*dp[div[z]-1][0])%mod);
    56     }
    57     for(int i=div[div.size()-1]+1;i<a.size();i++){
    58         ans*=(k-1);
    59         ans%=mod;
    60     }
    61     //cout<<ans<<endl;
    62 return ans;    
    63 }
    64 int main(){
    65     scanf("%lld%lld",&n,&k);
    66     FOR(i,1,n)scanf("%lld",&a[i]);
    67     for(int i=1;i<=n;i+=2){
    68         odd.push_back(a[i]);    
    69     }
    70     for(int i=2;i<=n;i+=2){
    71         even.push_back(a[i]);    
    72     }
    73     for(int i=0;i<odd.size();i++){
    74         if(odd[i]!=-1)odd_div.push_back(i);
    75         if(i!=0&&odd[i]==odd[i-1]&&odd[i]!=-1){
    76         cout<<0<<endl;
    77             return 0;
    78         }
    79         
    80     }
    81     for(int i=0;i<even.size();i++){
    82         if(i!=0&&even[i]==even[i-1]&&even[i]!=-1){
    83             cout<<0<<endl;
    84             return 0;
    85         }
    86         if(even[i]!=-1)even_div.push_back(i);
    87     }
    88     long long temp1,temp2;
    89     temp1=solve(odd,odd_div,1);
    90     temp2=solve(even,even_div,0);
    91     cout<<((temp1%mod)*(temp2%mod))%mod<<endl;
    92     return 0;
    93 }
    View Code
  • 相关阅读:
    gain 基尼系数
    luogu P5826 【模板】子序列自动机 主席树 vector 二分
    牛客挑战赛39 树与异或 离线 树上莫队 树状数组 约数
    4.22 省选模拟赛 三元组 manacher 回文自动机
    4.22 省选模拟赛 最优价值 网络流 最大权闭合子图
    4.18 省选模拟赛 消息传递 树剖 倍增 线段树维护等比数列
    luogu P4008 [NOI2003]文本编辑器 splay 块状链表
    牛客挑战赛39 密码系统 后缀数组
    luogu P1526 [NOI2003]智破连环阵 搜索+最大匹配+剪枝
    luogu P4095 [HEOI2013]Eden 的新背包问题 多重背包 背包的合并
  • 原文地址:https://www.cnblogs.com/ttttttttrx/p/10591456.html
Copyright © 2011-2022 走看看