• 哈理工新生赛 马拉车+贪心 最大密度子图 AC自动机+DP


    J.Symmys
    Time Limit: 1000 MS Memory Limit: 262144 K
    Total Submit: 50 (13 users) Total Accepted: 2 (2 users) Special Judge: No
    Description

    ClearY is not good at English. He often fails in his English test. To help him study English, his English teacher asks him to rewrite some sentence. But ClearY doesn’t want to rewrite; he wants to play games. He comes up with a solution to complete rewriting earlier. He uses both his hands to write but he can only write the same letter at the same time. Every time, he chooses a symmetry center, using his left hand writing from this position to left continually and using his right hand writing from this position to right continually. He doesn’t not care about writing same letter two or more times in one place. He wants to know how many symmetry center at least he need to choose to complete his work.

    Input

    First line contains an integer T (1 ≤ T ≤ 1000), represents there are T test cases.

    For each test case: one line contains a string of up to 106 lower case letters in length. It’s guaranteed that the sum length of all string will not exceed 5*106.

    Output

    For each test case, output one line containing "Case #X: Y"(without quotes), where X is the case number starting from 1, and Y is the minimum number of symmetry center at least ClearY need to choose.

    Sample Input

    2

    aba

    abbaab

    Sample Output

    Case #1: 1

    Case #2: 2

    Hint

    For the second sample case, he can write "abba"(position from 1 to 4) and "baab"(position from 3 to 6).

    #include<cstdio>//踩坑 for循环里不能每次求strlen
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    const int N=1e6+88;
    char str[N],t[N<<1];
    int p[N<<1];
    void Manacher(){
        t[0]='$',t[1]='#';
        int tot=2;
        int tc=strlen(str);
        for(int i=0;i<tc;++i) t[tot++]=str[i],t[tot++]='#';
        t[tot]=0;
        tc=strlen(t);
        int mx=0,id=0;
        for(int i=1;i<tc;++i) {
            p[i]=mx>i?min(p[2*id-i],mx-i):1;
            while(t[i+p[i]]==t[i-p[i]]) ++p[i];
            if(mx<i+p[i]) {
                mx=i+p[i];
                id=i;
            }
        }
    }
    int maxx[N<<1];
    int main(){
        int cas=1,T;
        for(scanf("%d",&T);T--;){
            scanf("%s",str);
            Manacher();
            int tot=0,length=2*strlen(str)+1;
            for(int i=1;i<=length;++i) maxx[i]=0;
            for(int i=1;i<=length;++i) maxx[i-p[i]+1]=max(maxx[i-p[i]+1],i+p[i]);
            int l=1,sum=0,mx=0;
            for(int i=1;i<=length;++i) maxx[i]=max(maxx[i-1],maxx[i]);
            while(l<=length) {
                l=maxx[l];
                ++sum;
            }
            printf("Case #%d: %d
    ",cas++,sum);
        }
    }
    F.GXZ is poison
    Time Limit: 1000 MS Memory Limit: 262144 K
    Total Submit: 14 (5 users) Total Accepted: 0 (0 users) Special Judge: No
    Description

    GXZ is a famous ACMer, and he is very strong and poisonous. His most powerful weapons are some poisonous strings, which will make your code full of bugs. Now there is a code, your task is to make them healthy, which means you are to repair your code by changing least number of characters so that the code doesn't contain any poisonous strings.

    To make it simpler, let's define "code" as a string composed of three characters: "G", "X", "Z".

    Input

      The input consists of multiple (at most 10) test cases. Each test case starts with a line containing one integers N (1 ≤ N ≤ 50), which is the number of poisonous strings. The following N lines gives N non-empty strings of length not greater than 20 containing only characters in "GXZ", which are the poisonous strings. The last line of the test case is a non-empty string of length not greater than 1000 containing only characters in "GXZ", which is the code to be repaired.

    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 code, print -1.

    Sample Input

    2

    GGG

    GGX

    GGGX

    2

    G

    ZX

    ZXGGZX

    3

    G

    X

    Z

    GXZ

    Sample Output

    Case 1: 1

    Case 2: 4

    Case 3: -1

    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=2008;
    char str[N];
    int dp[N][N],cas=1;
    struct AC{
        int ch[N][4],fail[N],sz,rt;
        bool flag[N];
        void init(){
            sz=rt=0;
            memset(ch[rt],-1,sizeof(ch[rt]));
            flag[rt]=0;
        }
        void newnode(){
            ++sz;
            for(int i=0;i<3;++i) ch[sz][i]=-1;
            flag[sz]=0;
        }
        void insert(char *str){
            int len=strlen(str);
            int u=rt;
            for(int i=0;i<len;++i) {
                int zc;
                if(str[i]=='G') zc=0;
                else if(str[i]=='X') zc=1;
                else zc=2;
                if(ch[u][zc]==-1) {
                    newnode();
                    ch[u][zc]=sz;
                }
                u=ch[u][zc];
            }
            flag[u]=1;
        }
        void build(){
            queue<int>Q;
            for(int i=0;i<3;++i) {
                if(ch[rt][i]==-1) ch[rt][i]=rt;
                else {
                    fail[ch[rt][i]]=rt;
                    Q.push(ch[rt][i]);
                }
            }
            while(!Q.empty()) {
                int u=Q.front();
                Q.pop();
                flag[u]|=flag[fail[u]];
                for(int i=0;i<3;++i) {
                    if(ch[u][i]==-1) ch[u][i]=ch[fail[u]][i];
                    else {
                        fail[ch[u][i]]=ch[fail[u]][i];
                        Q.push(ch[u][i]);
                    }
                }
            }
        }
        void DP(){
            memset(dp,-1,sizeof(dp));
            dp[0][0]=0;
            for(int i=1;str[i-1];++i) for(int j=0;j<=sz;++j) if(!flag[j]&&dp[i-1][j]!=-1)    
            for(int k=0;k<3;++k) {
            if(flag[ch[j][k]]) continue;
            if(str[i-1]=='G'&&k==0||str[i-1]=='X'&&k==1||str[i-1]=='Z'&&k==2) {
                if(dp[i][ch[j][k]]==-1) dp[i][ch[j][k]]=dp[i-1][j];
                else  dp[i][ch[j][k]]=min(dp[i][ch[j][k]],dp[i-1][j]);
            }
            else {
                if(dp[i][ch[j][k]]==-1) dp[i][ch[j][k]]=dp[i-1][j]+1;
                else  dp[i][ch[j][k]]=min(dp[i][ch[j][k]],dp[i-1][j]+1);
            }
            }
            int ans=0x3f3f3f3f,len=strlen(str);
            for(int i=0;i<=sz;++i) if(dp[len][i]!=-1) ans=min(ans,dp[len][i]);
            printf("Case %d: %d
    ",cas++,ans==0x3f3f3f3f?-1:ans);
        }
    }ac;
    int main(){
        int n;
        while(scanf("%d",&n)!=EOF){
            ac.init();
            for(int i=1;i<=n;++i) {
                scanf("%s",str);
                ac.insert(str);
            }
            ac.build();
            scanf("%s",str);
            ac.DP();
        }
    }
    C.Getting More Money Early
    Time Limit: 1000 MS Memory Limit: 262144 K
    Total Submit: 10 (6 users) Total Accepted: 0 (0 users) Special Judge: No
    Description

    There is an airline company. They accidentally found a new country with N cities. They want to build some airlines.

    But, before you have an airline, the start city and the end city must had built an airport. Building an airport need P unit(s) money. And the company has got the information that how much money a year some airline can earn. So, they would like to get profit as early as possible.

    Can you tell the company's director the earliest time they can start to get profits? But,we may get a decimal number. So, you just need to print the sum of the investment and the sum of profit in one year in the condition above.

    Input

    The first line contains an integer T (1 ≤ T ≤ 5), represents the number of test cases.

    For each test case:

    The first line contains three integers N, M, P (1 ≤ N ≤ 500, 1 ≤ M ≤ 1000, 1 ≤ P ≤ 1000)

    Each line of the following M lines three integers, ui, vi, pi(1 ≤ ui, vi ≤ N, ui != vi,1 ≤ pi ≤ 1000), which means the airline between ui and vi city, and the profit the airline can get each year. The data promise that the number of airlines between any two cities is less than or equal to one.

    Output

    For each test case, output one line containing "Case #X: "(without quotes) at first, where X is the case number starting from 1. Than print the answer of the two number we need. The first is the sum of the investment and the second is the profit the company can get every year in that condition.

    Sample Input

    1

    5 6 4

    1 5 3

    5 4 1

    4 2 2

    2 5 4

    1 2 1

    3 1 5

    Sample Output

    Case #1: 16 13

    Hint

    Case 1: you can choose city 1,2,3,5 and cost 16 unit of money and you can get the profit from the 1.23 year. That is the earliest time the company can start to get profit.

    这题被卡精度。。先扔坑

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int N=2000;
    const double eps=1e-7;
    const double INF=1e9+7;
    int n,m,head[N],tot,dis[N],S,T,q[N];
    double p;
    struct node{
        int v,next;
        double w;
    }e[N<<2];
    struct py{
        int u,v;
        double val;
    }ct[N];
    void add(int u,int v,double w){
        e[tot].v=v;e[tot].w=w;e[tot].next=head[u];head[u]=tot++;
    }
    bool bfs(){
        for(int i=S;i<=T;++i) dis[i]=-1;
        dis[S]=0;
        int l=0,r=0;
        q[r++]=S;
        while(l<r) {
            int u=q[l++];
            for(int i=head[u];~i;i=e[i].next){
                int v=e[i].v;
                if(dis[v]==-1&&e[i].w>eps) {
                    q[r++]=v;
                    dis[v]=dis[u]+1;
                    if(v==T) return true;
                }
            }
        } 
        return false;
    }
    double dfs(int s,double low){
         if(s==T||low<eps) return low;
         double ans=low,a;
         for(int i=head[s];~i;i=e[i].next) {
             if(e[i].w>0&&dis[e[i].v]==dis[s]+1){
                 a=dfs(e[i].v,min(e[i].w,ans));
                 if(a<eps) continue;
                 e[i].w-=a;
                 e[i^1].w+=a;
                 ans-=a;
                 if(ans<eps) return low;
             }
         }    
         if(low-ans<eps) dis[s]=-1;
         return low-ans;
    }
    int main(){
        int cas=1,Ta;
        for(scanf("%d",&Ta);Ta--;){
            scanf("%d%d%lf",&n,&m,&p);
            S=0,T=n+m+1;
            double ans=0;
            for(int i=1;i<=m;++i) scanf("%d%d%lf",&ct[i].u,&ct[i].v,&ct[i].val),ans+=ct[i].val;
            double l=0,r=1e6+7;
            for(int i=0;i<128;++i){
                double mid=(l+r)/2;
                for(int i=0;i<=n+m+1;++i) head[i]=-1;
                tot=0;
                for(int i=1;i<=m;++i) {
                    add(S,i,ct[i].val),add(i,S,0);
                    add(i,ct[i].u+m,INF),add(ct[i].u+m,i,0);
                    add(i,ct[i].v+m,INF),add(ct[i].v+m,i,0);
                }
                double ret=0;
                for(int i=1;i<=n;++i) add(i+m,T,mid*p),add(T,i+m,0);
                while(bfs()) ret+=dfs(S,INF);
                if(ans-ret<=eps) r=mid;
                else l=mid;
            }
            l-=eps;
            double ying=0,tt=0;
            for(int i=head[T];~i;i=e[i].next) if(l*p-e[i].w<=eps) tt+=p;
            ying=tt*l;
            int y=round(ying),t=round(tt);
            printf("Case #%d: %d %d
    ",cas++,t,y); 
        }
    }
  • 相关阅读:
    蒜厂年会|计蒜客2019蓝桥杯省赛 B 组模拟赛(一)
    抠图|计蒜客2019蓝桥杯省赛 B 组模拟赛(一)
    轻重搭配|计蒜客2019蓝桥杯省赛 B 组模拟赛(一)
    后缀字符串|计蒜客2019蓝桥杯省赛 B 组模拟赛(一)
    LIS|计蒜客2019蓝桥杯省赛 B 组模拟赛(一)
    倍数|计蒜客2019蓝桥杯省赛 B 组模拟赛(一)
    找质数|计蒜客2019蓝桥杯省赛 B 组模拟赛(一)
    2018年第九届蓝桥杯B组题C++汇总解析-fishers
    RepPoints v2: Verification Meets Regression for Object Detection
    i 的二次幂求和
  • 原文地址:https://www.cnblogs.com/mfys/p/8075520.html
Copyright © 2020-2023  润新知