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 }
    许愿弥生改二
  • 相关阅读:
    MySQL常用命令记录
    VM新安装centos7无法连接网络的问题
    nginx + tomcat实现负载均衡
    Redis集群分布(Windows版)
    7.2 基础知识ArrayMap
    7.1 基础知识Android消息处理机制
    6.5 Android硬件访问服务使用反射
    6.4 Android硬件访问服务编写HAL代码
    6.3 Android硬件访问服务APP代码
    6.2、Android硬件访问服务编写系统代码
  • 原文地址:https://www.cnblogs.com/LoveYayoi/p/6745393.html
Copyright © 2011-2022 走看看