• CF Round#626


    CF Round#626

    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;
    }
  • 相关阅读:
    angular模板
    Growth: 全栈增长工程师指南
    全栈增长工程师实战
    vue 快速搭建项目 iview
    ng-style
    教程视频链接
    内置对象
    对象—封装、继承
    对象—构造函数
    函数-理论
  • 原文地址:https://www.cnblogs.com/et3-tsy/p/12444747.html
Copyright © 2020-2023  润新知