Codeforces Round #674 (Div. 3)

突如其来的div3,赛后打了一下。

A - Floor Number

数学题答案是 1 + ⌈ n − 2 x ⌉ 1+\lceil \frac{n-2}{x} \rceil 1+xn2

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    
    
    IO;
    int T=1;
    cin>>T;
    while(T--)
    {
    
    
        int n,x;
        cin>>n>>x;
        if(n<=2) 
            cout<<1<<'\n';
        else
            cout<<1+(n-2+x-1)/x<<'\n';
    }
    return 0;
}

B - Symmetric Matrix

只要存在2×2小矩形是对称的并且边长是偶数就一定能够拼成大矩形,否则不行。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    
    
    IO;
    int T=1;
    cin>>T;
    while(T--)
    {
    
    
        bool ok=0;
        int n,m;
        cin>>n>>m;
        while(n--)
        {
    
    
            int a,b,c,d;
            cin>>a>>b>>c>>d;
            if(b==c) ok=1;
        }
        if(m%2) ok=0;
        if(ok) cout<<"YES\n";
        else cout<<"NO\n";
    }
    return 0;    
}

C - Increase and Copy

稍微转化一下,很明显如果加1,只需要每次把 a 1 a_1 a1,并且操作相同次数,先加1再复制结果一定更优。
此题有一个样例提示了我:当 n = 1000000000 n=1000000000 n=1000000000,答案是 63244 63244 63244,说明移动步数非常少。由此我们可以枚举+1的操作数然后就不难解决了。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
const int N=300010;
int main()
{
    
    
    IO;
    int T=1;
    cin>>T;
    while(T--)
    {
    
    
        int n;
        cin>>n;
        int res=0x3f3f3f3f;
        for(int i=0;i<=70000;i++)
        {
    
    
            int now=1;
            now+=i;
            if(now>=n)
            {
    
    
                res=min(res,i);
                break;
            }
            else
                res=min(res,i+(n-now+now-1)/now);
        }
        cout<<res<<'\n';
    }
    return 0;
}

E - Rock, Paper, Scissors

不难发现只需要找到互不相交,子串和为0的数量。
考虑前缀和数组 s i s_i si,如果 s i = s j s_i=s_j si=sj,说明 a i + 1 + a i + 2 + ⋯ + a j = 0 a_{i+1}+a_{i+2}+\dots+a_j=0 ai+1+ai+2++aj=0
然后用个map记录一下即可。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=200010;
ll a[N],s[N];
int n;
map<ll,int> mp;
int main()
{
    
    
    IO;
    int T=1;
    //cin>>T;
    while(T--)
    {
    
    
        cin>>n;
        mp.clear();
        for(int i=1;i<=n;i++)
        {
    
    
            cin>>a[i];
            s[i]=s[i-1]+a[i];
        }
        int now=0;
        int res=0;
        mp[0]=0;
        for(int i=1;i<=n;i++)
        {
    
    
            if(mp.count(s[i]))
            {
    
    
                if(now-1<=mp[s[i]])
                {
    
    
                    res++;
                    now=i;
                }
            }
            mp[s[i]]=i;
        }
        cout<<res<<'\n';
    }
    return 0;
}

D - Non-zero Segments

别问,问就是暴力
出牌顺序就6种,消顺序就8种,直接枚举即可。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
int n;
int a,b,c;
int e,f,g;
int main()
{
    
    
    IO;
    int T=1;
    //cin>>T;
    while(T--)
    {
    
    
        cin>>n;
        cin>>a>>b>>c;
        cin>>e>>f>>g;
        int cnt0=0;
        for(int i=0;i<1<<3;i++)
        {
    
    
            int x=e,y=f,z=g;
            int now1=min(a,x+z);
            if(i&1) 
            {
    
    
                z-=x-max(0,x-now1);
                x=max(0,x-now1);
            }
            else
            {
    
    
                x-=z-max(0,z-now1);
                z=max(0,z-now1);
            }
            int now2=min(b,y+x);
            if(i>>1&1)
            {
    
    
                x-=y-max(0,y-now2);
                y=max(0,y-now2);
            }
            else
            {
    
    
                y-=x-max(0,x-now2);
                x=max(0,x-now2);
            }
            int now3=min(c,y+z);
            if(i>>2&1)
            {
    
    
                z-=y-max(0,y-now3);
                y=max(0,y-now3);
            }
            else
            {
    
    
                y-=z-max(0,z-now3);
                z=max(0,z-now3);
            }
            cnt0=max(cnt0,now1+now2+now3);
        }
        for(int i=0;i<1<<3;i++)
        {
    
    
            int x=e,y=f,z=g;
            int now1=min(a,x+z);
            
            int now2=min(b,y+x);
            if(i>>1&1)
            {
    
    
                x-=y-max(0,y-now2);
                y=max(0,y-now2);
            }
            else
            {
    
    
                y-=x-max(0,x-now2);
                x=max(0,x-now2);
            }if(i&1) 
            {
    
    
                z-=x-max(0,x-now1);
                x=max(0,x-now1);
            }
            else
            {
    
    
                x-=z-max(0,z-now1);
                z=max(0,z-now1);
            }
            int now3=min(c,y+z);
            if(i>>2&1)
            {
    
    
                z-=y-max(0,y-now3);
                y=max(0,y-now3);
            }
            else
            {
    
    
                y-=z-max(0,z-now3);
                z=max(0,z-now3);
            }
            cnt0=max(cnt0,now1+now2+now3);
        }for(int i=0;i<1<<3;i++)
        {
    
    
            int x=e,y=f,z=g;
            
            int now2=min(b,y+x);
            if(i>>1&1)
            {
    
    
                x-=y-max(0,y-now2);
                y=max(0,y-now2);
            }
            else
            {
    
    
                y-=x-max(0,x-now2);
                x=max(0,x-now2);
            }
            int now3=min(c,y+z);
            if(i>>2&1)
            {
    
    
                z-=y-max(0,y-now3);
                y=max(0,y-now3);
            }
            else
            {
    
    
                y-=z-max(0,z-now3);
                z=max(0,z-now3);
            }int now1=min(a,x+z);
            if(i&1) 
            {
    
    
                z-=x-max(0,x-now1);
                x=max(0,x-now1);
            }
            else
            {
    
    
                x-=z-max(0,z-now1);
                z=max(0,z-now1);
            }
            cnt0=max(cnt0,now1+now2+now3);
        }for(int i=0;i<1<<3;i++)
        {
    
    
            int x=e,y=f,z=g;
            int now1=min(a,x+z);
            if(i&1) 
            {
    
    
                z-=x-max(0,x-now1);
                x=max(0,x-now1);
            }
            else
            {
    
    
                x-=z-max(0,z-now1);
                z=max(0,z-now1);
            }
            
            int now3=min(c,y+z);
            if(i>>2&1)
            {
    
    
                z-=y-max(0,y-now3);
                y=max(0,y-now3);
            }
            else
            {
    
    
                y-=z-max(0,z-now3);
                z=max(0,z-now3);
            }int now2=min(b,y+x);
            if(i>>1&1)
            {
    
    
                x-=y-max(0,y-now2);
                y=max(0,y-now2);
            }
            else
            {
    
    
                y-=x-max(0,x-now2);
                x=max(0,x-now2);
            }
            cnt0=max(cnt0,now1+now2+now3);
        }
        for(int i=0;i<1<<3;i++)
        {
    
    
            int x=e,y=f,z=g;
            int now1=min(a,x+z);
            
            int now3=min(c,y+z);
            if(i>>2&1)
            {
    
    
                z-=y-max(0,y-now3);
                y=max(0,y-now3);
            }
            else
            {
    
    
                y-=z-max(0,z-now3);
                z=max(0,z-now3);
            }if(i&1) 
            {
    
    
                z-=x-max(0,x-now1);
                x=max(0,x-now1);
            }
            else
            {
    
    
                x-=z-max(0,z-now1);
                z=max(0,z-now1);
            }
            int now2=min(b,y+x);
            if(i>>1&1)
            {
    
    
                x-=y-max(0,y-now2);
                y=max(0,y-now2);
            }
            else
            {
    
    
                y-=x-max(0,x-now2);
                x=max(0,x-now2);
            }
            cnt0=max(cnt0,now1+now2+now3);
        }for(int i=0;i<1<<3;i++)
        {
    
    
            int x=e,y=f,z=g;
            int now3=min(c,y+z);
            if(i>>2&1)
            {
    
    
                z-=y-max(0,y-now3);
                y=max(0,y-now3);
            }
            else
            {
    
    
                y-=z-max(0,z-now3);
                z=max(0,z-now3);
            }
            int now2=min(b,y+x);
            if(i>>1&1)
            {
    
    
                x-=y-max(0,y-now2);
                y=max(0,y-now2);
            }
            else
            {
    
    
                y-=x-max(0,x-now2);
                x=max(0,x-now2);
            }int now1=min(a,x+z);
            if(i&1) 
            {
    
    
                z-=x-max(0,x-now1);
                x=max(0,x-now1);
            }
            else
            {
    
    
                x-=z-max(0,z-now1);
                z=max(0,z-now1);
            }
            cnt0=max(cnt0,now1+now2+now3);
        }
        int cnt1=min(n,min(a,f)+min(b,g)+min(c,e));
        cout<<n-cnt0<<' '<<cnt1<<'\n';
    }
    return 0;
}

F - Number of Subsequences

首先不考虑问号,我们求子序列abc的个数可以用动态规划设计状态
状态表示:
f ( i , 0 ) f_{(i,0)} f(i,0)表示考虑前 i i i个字符,子序列 a a a的数目
f ( i , 1 ) f_{(i,1)} f(i,1)表示考虑前 i i i个字符,子序列 a b ab ab的数目
f ( i , 2 ) f_{(i,2)} f(i,2)表示考虑前 i i i个字符,子序列 a b c abc abc的数目
状态转移:
如果当前字符是 a a a,那么 f ( i , 0 ) = f ( i − 1 , 0 ) + 1 f_{(i,0)}=f_{(i-1,0)}+1 f(i,0)=f(i1,0)+1
如果当前字符是 b b b,那么 f ( i , 1 ) = f ( i − 1 , 1 ) + f ( i , 0 ) f_{(i,1)}=f_{(i-1,1)}+f_{(i,0)} f(i,1)=f(i1,1)+f(i,0)
如果当前字符是 c c c,那么 f ( i , 2 ) = f ( i − 1 , 2 ) + f ( i , 1 ) f_{(i,2)}=f_{(i-1,2)}+f_{(i,1)} f(i,2)=f(i1,2)+f(i,1)

此题目非常dt的地方就是因为问号的3种情况,导致有些转移不是那么简单
一个问号的3种情况会使得原来的 f ( i , 0 / 1 / 2 ) f_{(i,0/1/2)} f(i,0/1/2)翻3倍,而对于 f ( i , 0 ) f_{(i,0)} f(i,0)的转移会使得 + 1 +1 +1变成 + p k ( k 是 之 前 出 现 ? 的 数 目 ) +p^k(k是之前出现?的数目) +pk(k?)

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=200010;
const ll mod=1e9+7;
char s[N];
ll f[N][3];
int main()
{
    
    
    IO;
    int T=1;
    //cin>>T;
    while(T--)
    {
    
    
        int n;
        cin>>n;
        cin>>s+1;
        ll p=1;
        for(int i=1;i<=n;i++)
        {
    
    
            if(s[i]=='?')
            {
    
    
                f[i][0]=(3ll*f[i-1][0]+p)%mod;
                f[i][1]=(3ll*f[i-1][1]+f[i-1][0])%mod;
                f[i][2]=(3ll*f[i-1][2]+f[i-1][1])%mod;
                p=p*3%mod;
            }
            else if(s[i]=='a') 
            {
    
    
                f[i][0]=(f[i-1][0]+p)%mod;
                f[i][1]=f[i-1][1];
                f[i][2]=f[i-1][2];
            }
            else if(s[i]=='b')
            {
    
    
                f[i][0]=f[i-1][0];
                f[i][1]=(f[i-1][1]+f[i-1][0])%mod;
                f[i][2]=f[i-1][2];
            }
            else 
            {
    
    
                f[i][0]=f[i-1][0];
                f[i][1]=f[i-1][1];  
                f[i][2]=(f[i-1][2]+f[i-1][1])%mod;
            }
        }
        cout<<f[n][2]<<'\n';
        
    }
    return 0;
}

要加油哦~

猜你喜欢

转载自blog.csdn.net/Fighting_Peter/article/details/108877554