• 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
    ",num+1);
          for(int i=num-1; i >= 0 ; -- i)
            printf("%d %d
    ",tack[i],dp[tack[i]]);
            printf("%d %d
    ",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("
    ");    
            }
         return 0;    
    }
    View Code
  • 相关阅读:
    CSS颜色十六进制值规律
    linux清理内存命令
    一些常用的linux命令
    读《DOOM启示录》随想
    日常分享:关于时间复杂度和空间复杂度的一些优化心得分享(C#)
    .netcore过滤器有以下几种类型
    RabbitMQ十:重要方法简述(参数)
    git 配置 ssh
    log4net学习笔记
    redis下载与安装
  • 原文地址:https://www.cnblogs.com/Opaser/p/3742034.html
Copyright © 2020-2023  润新知