Codeforces Round #246 (Div. 2) D E

这题说的是给了一个字符串当前缀和后缀相同的时候就计算此时的 整个串种拥有这样的子串友多少个,没想到用KMP解 用0开头的那种类型的 KMP 今天刚好也学了一下,因为KMP的作用是找出最长前缀 KMP 后得到最后一个字符串在前缀当中的最长前缀然后即可以知道在这个最长前缀中可能还有比 最 长 前 缀 更 小 的 子 串 然 后 再 以 这  个 子 串 的 next 从最后开始KMP 然后就可以得到了次子串 这样一直下去 

#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
const int maxn = 100005;
int next[maxn],dp[maxn+5],tack[maxn];
char str[maxn];
void  getnext(){
    
     int j=0;
     int Len = strlen(str+1);
     next[0] = next[1] = 0;
     for( int i = 2 ; i <= Len ; i++ )
     {
             while( j && str[i]!=str[j+1] ) j=next[j];
             if(str[i]==str[j+1]) j++;
             next[i] = j; 
     }
}
int main()
{
     while(scanf("%s",str+1)==1){
       fill(dp,dp+maxn,1);
       getnext();
      // int Len= strlen(str);
       //for(int i = len-1 ;i < i++ )
      int Len = strlen(str+1);
      for( int i=Len ;i >0 ; i--)
         dp[next[i]]+=dp[i];
      int num = 0;
      int j=next[Len];
      while(j){
             tack[num++]=j;
             j=next[j];
      }
      printf("%d\n",num+1);
      for(int i=num-1; i >= 0 ; -- i)
        printf("%d %d\n",tack[i],dp[tack[i]]);
        printf("%d %d\n",Len,1);
     }
    return 0;
}
View Code

 E 这题原来是一个贪心 没想出来 对于每一个位置判断该位置用最小的 然后不断的去扩大他的范围然后 当n+1*n+1 范围内有别的字符存在的时候,或者超出范围 或者 在右上角这个位置可以填写别的字符 时就返回n 否则继续

#include <cstdio>
#include <string.h>
#include <iostream>
using namespace std;
const int maxn = 105;
char map[maxn][maxn];
bool in[maxn][maxn];
int N,M;
char tochar(int x,int y){
       for( int i='A' ; i <='Z' ; ++i ){
                bool falg = true;
             if( map[x-1][y]==i ) falg = false;
             if( map[x][y-1]==i )falg =false;
             if( map[x][y+1]==i ) falg =false;
             if( falg ) return i;
       }    
}
int jud(int x,int y,char &aim){
       
        int num = 1;
         aim= tochar(x,y);
        while(true){
           if( x + num > N || y + num > M) return num;
           if(in[x][y+num]) return num;    
           char to=tochar(x,y+num);
           if( to != aim) return num;
            num++;
        }
}
void out(int x,int y,int num ,char t){
      for(int i=x; i<x+num; ++i)
      for( int j =y ; j< y+num; ++j ){
        map[i][j] = t;
        in[i][j] =true;    
      }
}
int main(){
    
//    freopen("out.txt","w",stdout);
    memset(in,false,sizeof(in));
    
    memset(map,'a',sizeof(map));
    
    scanf("%d%d",&N,&M);
     
       for( int i = 1 ; i <= N ; ++ i)
         for( int j =1 ; j <= M ; ++ j)
            if(in[i][j]==false){
                char t;
                int num= jud(i,j,t);    
                   out(i,j,num,t);
            }
        
        for( int i=1 ;i <= N ; ++ i){
              
               for( int j =1 ;j<=M  ; ++ j)
                   printf("%c",map[i][j]);
               printf("\n");    
        }
     return 0;    
}
View Code

 

 

posted @ 2014-05-21 23:08  来自大山深处的菜鸟  阅读(175)  评论(0编辑  收藏  举报