CF Round#625

CF Round#625

A.水~

B.数学

题意:

分别给定你两个长度为n,m的字符串A,B,都是由0,1构成

矩阵每个元素aij=Ai*Bj

现在给定k,问这个矩阵当中有多少个子矩阵,使得子矩阵的所有元素为1,且1的数量刚好为k

思路:

这道题目看起来很难,但是稍加分析,不难发现,所求的k是个面积,那么面积就应该由长乘宽组成,换句换说,我们现在就是要将k进行拆解两个整数,使得k=m * (k/m),那么为了子矩阵内全是1,那么我们无非就要使长或宽均是1。

那么问题就转变成了在A上寻找一段长度为m连续为1的子串,B上寻找长度为k/m连续为1的子串,根据乘法原理,相乘即可。

那么问题的关键点就成为了长度为k,连续为1的子串有多少

On 的做法就是从左往右扫一遍,初始化cur=0,遇到1,cur++,savea[cur]++;遇到0,cur=0;

处理后,再从右往左扫一遍,savea[i-1]+=savea[i],这样做的目的模拟一下下就懂了,savea[x]就是长度为x的数量了


#include<iostream>
#include<cstring>
#include<cmath> 
using namespace std;
#define INF 1e10+5
#define MAXN 50010
#define MINN -105
typedef long long int LL;
int main()
{   
    LL n,m,k;
    LL a[MAXN],b[MAXN],savea[MAXN],saveb[MAXN];
    memset(savea,0,sizeof(savea));
    memset(saveb,0,sizeof(saveb));
    cin>>n>>m>>k;
    LL cur=0;
    for(LL i=1;i<=n;i++)
    {
        cin>>a[i];
        if(a[i])cur++;
        else cur=0;
        savea[cur]++;
    }
    for(LL i=n;i>=2;i--)
        savea[i-1]+=savea[i];
    cur=0;
    for(LL i=1;i<=m;i++)
    {
        cin>>b[i];
        if(b[i])cur++;
        else cur=0;
        saveb[cur]++;
    }
    for(LL i=m;i>=2;i--)
        saveb[i-1]+=saveb[i];
    LL ans=0;
    for(LL i=1;i<=k;i++)
    {
        if(i>n)break;
        if((k/i)>m)continue;
        if(k/i*i==k)
            ans+=savea[i]*saveb[k/i];
    }
    cout<<ans<<endl;
    return 0;
}

C.模拟

这题看懂题目意思很重要,他是给一个字符串由 () 组成,问你最小操作长度多长,使得括号匹配正确。每次操作可以任意调换长度内的顺序.

思路:首先,他只能调换顺序,也就是是"("和")"的数量要一样,其次,你从左往右扫,to记录当前(的数量,如果为正,说明(比)多多少,也就是是只要为正就可以完全抵消,如果为负,那么要记录te,进行交换的区间是多长,一旦to==0,那么就要更新ans,清空te

#include<iostream>
#include<cstring>
#include<string>
using namespace std;
#define INF 1e10+5
#define MAXN 105
#define MINN -105
typedef long long int LL;
int main() 
{
    int n ;
    string s ;
    cin>>n>>s;
    int c=0,to=0,te=0,ans=0;
    for(int i=0;i<n;++i)(s[i]==')')?--c:++c ;
    if(c){cout<<-1<<endl;return 0;}
    for(int i=0;i<n;++i)
    {
        if(s[i]=='(')
        {
            if(to<0)te++;
            to++;
        }
        else to--;
        if(to==0)ans+=(te*2),te=0;
    }
cout<<ans<<endl;
}

猜你喜欢

转载自www.cnblogs.com/et3-tsy/p/12444747.html