zoukankan      html  css  js  c++  java
  • 【codeforces #282(div 1)】AB题解

    A. Treasure
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Malek has recently found a treasure map. While he was looking for a treasure he found a locked door. There was a string s written on the door consisting of characters '(', ')' and '#'. Below there was a manual on how to open the door. After spending a long time Malek managed to decode the manual and found out that the goal is to replace each '#' with one or more ')' characters so that the final string becomes beautiful.

    Below there was also written that a string is called beautiful if for each i (1 ≤ i ≤ |s|) there are no more ')' characters than '(' characters among the first i characters of s and also the total number of '(' characters is equal to the total number of ')' characters.

    Help Malek open the door by telling him for each '#' character how many ')' characters he must replace it with.

    Input

    The first line of the input contains a string s (1 ≤ |s| ≤ 105). Each character of this string is one of the characters '(', ')' or '#'. It is guaranteed that s contains at least one '#' character.

    Output

    If there is no way of replacing '#' characters which leads to a beautiful string print  - 1. Otherwise for each character '#' print a separate line containing a positive integer, the number of ')' characters this character must be replaced with.

    If there are several possible answers, you may output any of them.

    Sample test(s)
    input
    (((#)((#)
    
    output
    1
    2
    
    input
    ()((#((#(#()
    
    output
    2
    2
    1
    input
    #
    
    output
    -1
    
    input
    (#)
    
    output
    -1
    


    贪心。


    (表示1,)表示-1。


    满足条件则前缀和时刻都要>=0。


    那么遇到#我们仅仅让他表示一个)。前缀和仅仅-1。遇到最后一个#再把前面的债还清。


    一開始WA了,由于我遇到最后一个#就无论前缀和了。


    因此(#(这种数据就过不了。

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #define M 100000+5
    using namespace std;
    char s[M];
    int ans[M];
    int main()
    {
            scanf("%s",s);
    	int l=strlen(s);
    	int la,now=0,tot=0;
    	for (int i=0;i<l;i++)
    	{
    	    if (s[i]=='#')
    		{
    			ans[++tot]=1;
    			now--;
    			la=i;
    		}
    		if (s[i]=='(') now++;
    		if (s[i]==')') now--;
    		if (now<0)
    		{
    			puts("-1");
    			return 0;
    		}
    	}
    	int x=0;
    	for (int i=l-1;i>la;i--)
    	{
    		if (s[i]=='(')
    			x--;
    	    else x++;
    	    if (x<0)
    	    {
    			puts("-1");
    		    return 0;
    	    }
    	}
    	ans[tot]+=now;
    	for (int i=1;i<=tot;i++)
    		printf("%d
    ",ans[i]);
    	return 0;
    }
    

    B. Obsessive String
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Hamed has recently found a string t and suddenly became quite fond of it. He spent several days trying to find all occurrences of t in other strings he had. Finally he became tired and started thinking about the following problem. Given a string s how many ways are there to extract k ≥ 1 non-overlapping substrings from it such that each of them contains string t as a substring? More formally, you need to calculate the number of ways to choose two sequences a1, a2, ..., ak and b1, b2, ..., bk satisfying the following requirements:

    • k ≥ 1
    •   t is a substring of string saisai + 1... sbi (string s is considered as 1-indexed).

    As the number of ways can be rather large print it modulo 109 + 7.

    Input

    Input consists of two lines containing strings s and t (1 ≤ |s|, |t| ≤ 105). Each string consists of lowercase Latin letters.

    Output

    Print the answer in a single line.

    Sample test(s)
    input
    ababa
    aba
    
    output
    5
    
    input
    welcometoroundtwohundredandeightytwo
    d
    
    output
    274201
    
    input
    ddd
    d
    
    output
    12
    

    kmp+dp。


    首先用kmp高速求出每一位的ok[i],也就是从i到ok[i]包括t,且ok[i]最小。


    然后进行dp:

    f[i]表示a[1]=i的方案数。这显然要倒着做。


    f[i]=sigma(sigma(f[ok[i]+1...n-1)+sigma(f[ok[i]+2...n-1]...+f[n-1]))


    维护后缀和sum[i]表示i到n-1的f值得后缀和。


    再维护后缀和的后缀和ss[i]表示i到n-1的sum[i]的后缀和。


    于是f[i]=ss[ok[i]+1],转移变成O(1)了!

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    #define mod 1000000007
    #define M 100000+5
    using namespace std;
    int ss[M],ne[M],n,m,ok[M],sum[M],f[M];
    char s[M],t[M];
    void Getfail()
    {
    	ne[0]=0;
    	ne[1]=0;
    	for (int i=1;i<m;i++)
    	{
    		int j=ne[i];
    		while (j&&t[i]!=t[j])
    			j=ne[j];
    		ne[i+1]=t[i]==t[j]?

    j+1:0; } } void Find() { Getfail(); int j=0; int now=0; for (int i=0;i<n;i++) ok[i]=n; for (int i=0;i<n;i++) { while (j&&t[j]!=s[i]) j=ne[j]; if (t[j]==s[i]) j++; if (j==m) { for (int k=now;k<=i-m+1;k++) ok[k]=min(i,ok[k]); now=i-m+2; j=ne[j]; } } } int main() { scanf("%s",s); scanf("%s",t); n=strlen(s),m=strlen(t); Find(); for (int i=n-1;i>=0;i--) { f[i]=n-1-(ok[i]-1); f[i]=(f[i]+ss[ok[i]+1])%mod; sum[i]=(sum[i+1]+f[i])%mod; ss[i]=(ss[i+1]+sum[i])%mod; } cout<<sum[0]%mod<<endl; return 0; }



  • 相关阅读:
    xib中Autolayout的使用
    duplicate symbol _gestureMinimumTranslation in:
    oracle数字字符串是否有非法数字
    ora-01536 space quota exceeded for tablespace
    Linux core 文件(二)
    Linux core 文件(一)
    完全卸载oracle11g步骤
    oracle11gr2 for windows 32-bit win7安装与卸载
    Oracle的几个概念:数据库名,全局数据库名,SID,实例,命名空间,schema
    cut 字符截取命令
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/6743024.html
Copyright © 2011-2022 走看看