码迷,mamicode.com
首页 > 其他好文 > 详细

7-28测试

时间:2017-07-28 23:44:54      阅读:244      评论:0      收藏:0      [点我收藏+]

标签:空字符串   code   next   序号   efi   时间   getch   序列   mem   

 

假发通过了不懈的努力,得到了将军家门锁的密码(一串小写英文字母)。但是假发被十四和猩猩他们盯上了,所以假发需要把密码传递出去。因为假发不想十四他们发现几松门前贴的小纸条就是将军家的密码,所以他加密了密码(新八:听起来有点诡异)。加密方法如下:随机地,在密码中任意位置插入随机长度的小写字符串。

不过,假发相信银桑和他那么多年小学同学,一定能猜中密码是什么的(新八:银桑什么时候成攮夷志士了!!!)。可是,写完了小纸条之后,假发觉得有点长,就想截去头和尾各一段(可以为空),让剩下的中间那一段依然包含真~密码。想着想着,假发就想知道有多少种可行方案。结果在沉迷于稿纸之际,假发被投进了狱门岛(新八:……)。于是,就由你计算了。  

 

输入

 

两行非空字符串,纯小写英文字母,第一行是加密后的密码,第二行是原密码。

第一行长度不超过300000,第二行不超过200。

 

输出

 

一行,有多少种方案。注意:不剪也是一种方案。

 

样例输入

abcabcabc
cba

样例输出

9

提示

 

 


【样例解释】


(L,R)表示一种方案,其中LR分别表示截去头和尾的长度。这9钟方案分别是(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2)


【数据说明】


    30%的数据满足第一行长度不超过1000。

一拿到此题懵逼,开始以为是裸裸的KMP,后来发现暴力就是可以水过。f[i][j]表示第i个节点之后最近的j字符的位置。这样我们每次枚举起点在原字符串种的位置,一次次往下跳即可。
#include<iostream> 
#include<cstdio> 
#include<algorithm> 
#include<cstring> 
#define N 300005 
using namespace std; 
char stra[N+10],strb[N+10]; 
int lena,lenb,last; 
int next[N+10][26],dictionary[26]; 
long long ans; 
int main() 
{ 
    scanf("%s %s",stra+1,strb+1); 
    int lena=strlen(stra+1); 
    int lenb=strlen(strb+1); 
    for(int i=lena;i>=1;i--) 
    { 
        memcpy(next[i],dictionary,sizeof(next[i])); 
        dictionary[stra[i]-a]=i; 
    } 
    for(int i=1;i<=lena;i++) 
    if(stra[i]==strb[1]) 
    { 
        int p=i,t=1; 
        bool flag=1; 
        while(t<lenb) 
        { 
            p=next[p][strb[++t]-a]; 
            if(p==0) 
            { 
                flag=0; 
                break; 
            } 
        } 
        if(!flag) continue; 
        ans+=(lena-p+1)*(i-last); 
        last=i; 
    } 
    cout<<ans<<endl; 
} 

题 B: 独立集

时间限制: 1 Sec  内存限制: 128 MB
提交: 155  解决: 32
[提交][状态][讨论版]

题目描述

 

有一天,一个名叫顺旺基的程序员从石头里诞生了。又有一天,他学会了冒泡排序和独立集。在一个图里,独立集就是一个点集,满足任意两个点之间没有边。于是他就想把这两个东西结合在一起。众所周知,独立集是需要一个图的。那么顺旺基同学创造了一个算法,从冒泡排序中产生一个无向图。

    这个算法不标准的伪代码如下:

 

procedure bubblesortgraph(n, a[]) :

/*输入:点数n,1到n的全排列a。

输出:一个点数为n的无向图G。*/

   创建一个有n个点,0条边的无向图G。

repeat

 swapped = false

     for i 1 n-1 :

            if a[i] > a[i + 1] :

                           在G中连接点a[i]和点a[i + 1]

                  交换a[i]和a[i + 1]

            swapped = true

until not swapped

                      输出图G。

                      //结束。

 

        那么我们要算出这个无向图G最大独立集的大小。但是事情不止于此。顺旺基同学有时候心情会不爽,这个时候他就会要求你再回答多一个问题:最大独立集可能不是唯一的,但有些点是一定要选的,问哪些点一定会在最大独立集里。今天恰好他不爽,被他问到的同学就求助于你了。

 

输入

 

两行。第一行为N,第二行为1到N的一个全排列。 

输出

 

 两行。第一行输出最大独立集的大小,第二行从小到大输出一定在最大独立集的点的编号(输入时的序号)。

 

样例输入

3
3 1 2

样例输出

2
2 3

提示

 

【数据范围】


    30%的数据满足 N<=16


    60%的数据满足 N<=1,000


    100%的数据满足 N<=100,000 

哈哈刚写过求LIS的nlogn方法,就考到了~  ~开心。
这道题就是求一个LIS,问哪些点一定在LIS的序列里。我们把每个点向左和向右的LIS算出来,如果相加=最长上升子序列数+1则代表这个点可以是最长上升子序列中的一点。如果这个二元组没有重复出现过,就代表它不能被替换。
#include<iostream> 
#include<algorithm> 
#include<cstdio> 
#include<cstring> 
#include<cmath> 
#include<cstdlib> 
#include<vector> 
#include<map> 
using namespace std; 
typedef long long ll; 
typedef long double ld; 
typedef pair<int,int> pr; 
const double pi=acos(-1); 
#define rep(i,a,n) for(int i=a;i<=n;i++) 
#define per(i,n,a) for(int i=n;i>=a;i--) 
#define Rep(i,u) for(int i=head[u];i;i=Next[i]) 
#define clr(a) memset(a,0,sizeof(a)) 
#define pb push_back 
#define mp make_pair 
#define fi first 
#define sc second 
#define pq priority_queue 
#define pqb priority_queue <int, vector<int>, less<int> > 
#define pqs priority_queue <int, vector<int>, greater<int> > 
#define vec vector 
ld eps=1e-9; 
ll pp=1000000007; 
ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;} 
ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;} 
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); } 
//void add(int x,int y,int z){ v[++e]=y; next[e]=head[x]; head[x]=e; cost[e]=z; } 
int dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1}; 
ll read(){ ll ans=0; char last= ,ch=getchar(); 
while(ch<0 || ch>9)last=ch,ch=getchar(); 
while(ch>=0 && ch<=9)ans=ans*10+ch-0,ch=getchar(); 
if(last==-)ans=-ans; return ans; 
} 
#define N 100005 
map<pr,int> Map; 
int B[N],a[N],Left[N],n,b[N],Right[N],Len; 
void init() 
{ 
    n=read(); 
    rep(i,1,n) 
    a[i]=read(); 
}    
void LIS() 
{ 
    B[1]=a[1];int len=1;Left[1]=1; 
    for(int i=2;i<=n;i++) 
    { 
        if(a[i]>B[len]) B[++len]=a[i]; 
        int pos=lower_bound(B+1,B+1+len,a[i])-B; 
        B[pos]=a[i]; 
        Left[i]=pos; 
    } 
    Len=len; 
} 
void  RE_LIS() 
{ 
    memset(B,0,sizeof(B)); 
    for(int i=1;i<=n;i++) b[i]=a[i]; 
    for(int i=1;i<=n;i++) a[i]=-b[n-i+1]; 
    B[1]=a[1];int len=1;Right[n]=1; 
    for(int i=2;i<=n;i++) 
    { 
        if(a[i]>B[len]) B[++len]=a[i]; 
        int pos=lower_bound(B+1,B+1+len,a[i])-B; 
        B[pos]=a[i]; 
        Right[n-i+1]=pos; 
    } 
      
} 
void Debug() 
{ 
    for(int i=1;i<=n;i++) 
        cout<<Left[i]<< <<Right[i]<<endl; 
} 
int main() 
{   
    init(); 
    LIS(); 
    RE_LIS(); 
    //Debug(); 
    cout<<Len<<endl; 
    for(int i=1;i<=n;i++) 
    if(Left[i]+Right[i]-1==Len) 
    { 
        Map[mp(Left[i],Right[i])]++; 
    } 
    for(int i=1;i<=n;i++) 
    if(Map[mp(Left[i],Right[i])]==1) printf("%d ",i); 
} 
  

 

7-28测试

标签:空字符串   code   next   序号   efi   时间   getch   序列   mem   

原文地址:http://www.cnblogs.com/dancer16/p/7252763.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!