zoukankan      html  css  js  c++  java
  • HDU 2457 DNA_repair

    DNA repair

    Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 2530    Accepted Submission(s): 1356
    Problem Description

    Biologists finally invent techniques of repairing DNA that contains segments causing kinds of inherited diseases. For the sake of simplicity, a DNA is represented as a string containing characters 'A', 'G' , 'C' and 'T'. The repairing techniques are simply to change some characters to eliminate all segments causing diseases. For example, we can repair a DNA "AAGCAG" to "AGGCAC" to eliminate the initial causing disease segments "AAG", "AGC" and "CAG" by changing two characters. Note that the repaired DNA can still contain only characters 'A', 'G', 'C' and 'T'.

    You are to help the biologists to repair a DNA by changing least number of characters.

     

    Input

    The input consists of multiple test cases. Each test case starts with a line containing one integers N (1 ≤ N ≤ 50), which is the number of DNA segments causing inherited diseases.
    The following N lines gives N non-empty strings of length not greater than 20 containing only characters in "AGCT", which are the DNA segments causing inherited disease.
    The last line of the test case is a non-empty string of length not greater than 1000 containing only characters in "AGCT", which is the DNA to be repaired.

    The last test case is followed by a line containing one zeros.

     

    Output

    For each test case, print a line containing the test case number( beginning with 1) followed by the
    number of characters which need to be changed. If it's impossible to repair the given DNA, print -1.
     

    Sample Input

    2
    AAA
    AAG
    AAAG
    2
    A
    TG
    TGAATG
    4
    A
    G
    C
    T
    AGT
    0
     

    Sample Output

    Case 1: 1
    Case 2: 4
    Case 3: -1
     
    基础的AC自动机DP,按长度一层层前向转移
     
      1 #include <iostream>
      2 #include <cstdlib>
      3 #include <cstdio>
      4 #include <algorithm>
      5 #include <string>
      6 #include <cstring>
      7 #include <cmath>
      8 #include <map>
      9 #include <stack>
     10 #include <set>
     11 #include <vector>
     12 #include <queue>
     13 #include <time.h>
     14 #define eps 1e-7
     15 #define INF 0x3f3f3f3f
     16 #define MOD 1000000007
     17 #define rep0(j,n) for(int j=0;j<n;++j)
     18 #define rep1(j,n) for(int j=1;j<=n;++j)
     19 #define pb push_back
     20 #define set0(n) memset(n,0,sizeof(n))
     21 #define ll long long
     22 #define ull unsigned long long
     23 #define iter(i,v) for(edge *i=head[v];i;i=i->next)
     24 //#define max(a,b) (a>b?a:b)
     25 //#define min(a,b) (a<b?a:b)
     26 //#define OJ
     27 using namespace std;
     28 const int MAXINT = 1110;
     29 const int MAXNODE = 1110;
     30 const int MAXEDGE = 1110;
     31 int n, T;
     32 char s[MAXINT];
     33 struct node {
     34     node *fail;
     35     node *c[4];
     36     int bad;
     37     int nd[MAXINT]; //for a string of length i, least change required to reach this state
     38 };
     39 int toint(char c) {
     40     switch (c) {
     41     case 'A': return 0;
     42     case 'C': return 1;
     43     case 'G': return 2;
     44     case 'T': return 3;
     45     }
     46     return 0;
     47 }
     48 struct ac_automaton {
     49     node mp[MAXNODE];
     50     node *root, *pre;
     51     node *q[MAXNODE];
     52     int cnt;
     53     ac_automaton() {
     54         memset(mp, 0, sizeof(mp));
     55         memset(q, 0, sizeof(q));
     56         cnt = 0;
     57         root = new_node();
     58         pre = root;
     59     }
     60     void clear() {
     61         memset(mp, 0, sizeof(mp));
     62         memset(q, 0, sizeof(q));
     63         cnt = 0;
     64         root = new_node();
     65         pre = root;
     66     }
     67     node *new_node() {
     68         memset(mp[cnt].nd, 0x3f3f, sizeof(mp[cnt].nd));
     69         return &mp[cnt++];
     70     }
     71     void add(int w) {
     72         if (!pre->c[w]) pre->c[w] = new_node();
     73         pre = pre->c[w];
     74     }
     75     void danger() {
     76         pre->bad = 1;
     77     }
     78     void init() {
     79         pre = root;
     80     }
     81     void get_fail() {
     82         int h = 0, t = 0;
     83         node *p, *tmp;
     84         q[t++] = root;
     85         root->fail = NULL;
     86         while (h != t) {
     87             p = q[h++];
     88             rep0(i, 4) {
     89                 if (p->c[i]) {
     90                     if (p == root) p->c[i]->fail = root;
     91                     else {
     92                         tmp = p->fail;
     93                         while (tmp) {
     94                             if (tmp->c[i]) {
     95                                 p->c[i]->bad |= tmp->c[i]->bad;
     96                                 p->c[i]->fail = tmp->c[i];
     97                                 break;
     98                             }
     99                             tmp = tmp->fail;
    100                         }
    101                         if (!tmp) p->c[i]->fail = root;
    102                     }
    103                     q[t++] = p->c[i];
    104                 }
    105                 else {
    106                     p->c[i] = p->fail&&p->fail->c[i] ? p->fail->c[i] : root;
    107                 }
    108             }
    109         }
    110     }
    111     void solve(char *s) {
    112         int l = strlen(s);
    113         root->nd[0] = 0;
    114         rep0(i, l) {
    115             rep0(j, cnt) {
    116                 if (mp[j].nd[i] != INF) {
    117                     rep0(k, 4) {
    118                         node *p = mp[j].c[k];
    119                         if (!p || p->bad) continue;
    120                         p->nd[i + 1] = min(p->nd[i + 1], mp[j].nd[i] + ((toint(s[i]) == k) ? 0 : 1));
    121                     }
    122                 }
    123             }
    124         }
    125         int ans = INF;
    126         rep0(i, cnt) {
    127             if (!mp[i].bad) {
    128                 ans = min(ans, mp[i].nd[l]);
    129             }
    130         }
    131         printf("Case %d: %d
    ", T, ans == INF ? -1 : ans);
    132     }
    133 } acm;
    134 int read() {
    135     char c = getchar(); int f = 1, x = 0;
    136     while (!isdigit(c)) { if (c == '-') f = -1; c = getchar(); }
    137     while (isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); }
    138     return f * x;
    139 }
    140 char get_ch() {
    141     char c = getchar();
    142     while (!isalpha(c)) c = getchar();
    143     return c;
    144 }
    145 
    146 void get_input();
    147 void work();
    148 int main() {
    149     freopen("in.txt", "r", stdin);
    150     freopen("out.wa", "w", stdout);
    151     while (++T) {
    152         scanf("%d", &n);
    153         if (!n) break;
    154         acm.clear();
    155         get_input();
    156         work();
    157     }
    158     return 0;
    159 }
    160 void work() {
    161     acm.solve(s);
    162 }
    163 void get_input() {
    164     rep0(i, n) {
    165         scanf("%s", s);
    166         int l = strlen(s);
    167         rep0(j, l) acm.add(toint(s[j]));
    168         acm.danger();
    169         acm.init();
    170     }
    171     acm.get_fail();
    172     scanf("%s", s);
    173 }
    许愿弥生改二
  • 相关阅读:
    搜索文字高亮
    聊天 页面 定位overflow: scroll 原生滚动,iOS下会不流畅,
    MySQL技术专题(X)该换换你的数据库版本了,让我们一同迎接8.0的到来哦!(初探篇)
    Zookeeper原理系列-Paxos协议的原理和Zookeeper中的应用分析
    【Spring技术原理】Aspectj和LoadTimeWeaving的动态代理技术实现指南
    【SpringBoot技术专题】「权限校验专区」Shiro整合JWT授权和认证实现
    👊 Spring技术原理系列-从零开始教你SpringEL表达式使用和功能分析讲解指南(上篇)
    SpringBoot-技术专区-教你如何开发一个”可移植“的轻量级文件服务项目系统!
    ☕【Java技术指南】「JPA编程专题」让你不再对JPA技术中的“持久化型注解”感到陌生了!
    【SpringCloud技术专题】「Eureka源码分析」从源码层面让你认识Eureka工作流程和运作机制(下)
  • 原文地址:https://www.cnblogs.com/LoveYayoi/p/6745393.html
Copyright © 2011-2022 走看看