2015 ICPC 沈阳网赛 解题报告

来源:互联网 发布:撩淘宝客服 编辑:程序博客网 时间:2024/05/16 01:28

        这把打得真是水,简直不能忍,题数就差了2题,木有出线,我要背锅。。


1012 Largest Point

        这题我并没有码,讲讲思路就好了。要求一个式子最大值,分析一下发现可以贪心搞,把最大2个数、最小2个数、绝对值最小2个数找出来,注意不用sort,然后暴力试这6个数就好了。学弟很给力1A了。


1006 Fang Fang

        如果字符串中全是f,那么就是(len+1)/2。如果是c和f,随便把一个c循环到开头,检查两个c之间和最后一个c到末尾的f是否达到2个以上。然而我写了bug坑了几发。

#include <iostream>     #include <cstdio>     #include <algorithm>     #include <set>    #include <vector>    #include <string.h>    #include <queue>  #include <map>  using namespace std;#define ll long longchar str[1000010];char str2[1000010];int main(){    int t;    cin>>t;    int cas=0;        while(t--){        cas++;        scanf("%s",str);        int len=strlen(str);        int firstC=-1;        for(int i=0;i<len;i++){            if(str[i]=='c'){                firstC=i;                break;            }        }                printf("Case #%d: ",cas);        bool woca=0;        for(int i=0;i<len;i++){            if(str[i]!='c'&&str[i]!='f'){                woca=1;break;            }        }        if(woca){            printf("-1\n");            continue;        }        if(firstC==-1){            printf("%d\n",(len+1)>>1);        }else{            for(int i=firstC;i<len;i++){                str2[i-firstC]=str[i];            }            for(int i=0;i<firstC;i++){                str2[i+len-firstC]=str[i];            }            bool ok=1;            int cnt=0;            int ans=0;            for(int i=1;i<=len;i++){                if(str2[i]=='c'||i==len){                    if(cnt<2){                        ok=0;break;                    }                    cnt=0;                    ans++;                }else{                    cnt++;                }            }            if(ok){                printf("%d\n",ans);            }else{                printf("-1\n");            }        }    }    return 0;}

1010 Jesus Is Here

        这题怎么看怎么像斐波那契数,但是解法却无关。从小到大,递推(可以理解为dp)求出每个串有多少个c,第一个c离左边多少,最后一个c离右边多少,还有长度。si很自然地就是si-2和si-1拼起来,答案就是左半部分的答案ans(i-2)+右半部分的答案ans(i-1)+横跨两边的组数,用递推出来的信息算一下就好了。

#include <iostream>     #include <cstdio>     #include <algorithm>     #include <set>    #include <vector>    #include <string.h>    #include <queue>  #include <map>  using namespace std;#define ll long longconst int maxn = 201320;const ll mod = 530600414;ll tol[maxn];ll tor[maxn];ll cnt[maxn];ll ans[maxn];ll len[maxn];int main(){    int t;    cin>>t;    int cas=0;    int n;        tol[3]=1;    tor[3]=3;    cnt[3]=1;    len[3]=3;    tol[4]=3;    tor[4]=3;    cnt[4]=1;    len[4]=5;    //    //ans[3]=1;    ans[4]=1;    for(int i=5;i<=201314;i++){        cnt[i]=cnt[i-2]+cnt[i-1];        cnt[i]%=mod;        tol[i]=tol[i-2]+tol[i-1]+cnt[i-1]*len[i-2];        tol[i]%=mod;        tor[i]=tor[i-1]+tor[i-2]+cnt[i-2]*len[i-1];        tor[i]%=mod;        len[i]=len[i-2]+len[i-1];        len[i]%=mod;        //        ans[i]=ans[i-1]+ans[i-2];        ans[i]+=tor[i-2]*cnt[i-1];        ans[i]+=tol[i-1]*cnt[i-2];        ans[i]%=mod;        ll tmp = cnt[i-2]*cnt[i-1];        tmp%=mod;        ans[i]+=mod;        ans[i]-=tmp;        ans[i]%=mod;    }    ans[3]=1;    ans[4]=1;    while(t--){                cas++;        scanf("%d",&n);        printf("Case #%d: %I64d\n",cas,ans[n]);    }        return 0;}

1003 Minimum Cut

        求一个无向图的最小割,必须恰好包含给出的生成树的一条边。做法是以生成树为骨架,多出来边uv,就把u-v在生成树上的路径上所有边加上权1,到最后最小边权就是答案。用离线LCA算法+打标实现。到最后dfs一次读取标记的信息,得到每条边的权,找出最小值即可。唉,这个处理方法前几天CF做过的,而且是自己想出的,比赛时居然卡题了,逗比如我。。。

#include <iostream>   #include <cstdio>   #include <algorithm>   #include <set>  #include <vector>  #include <string.h>  using namespace std;     #define ll long long    const int mod=1000000007;  ll INF=1000000000000000000LL;  #define maxn 20010    //输入挂 void scanf_(int &num){    char in;    bool neg=false;    while(((in=getchar()) > '9' || in<'0') && in!='-') ;    if(in=='-')    {      neg=true;      while((in=getchar()) >'9' || in<'0');    }    num=in-'0';    while(in=getchar(),in>='0'&&in<='9')      num*=10,num+=in-'0';    if(neg)      num=0-num;  }int n,m;  int tote;  int a[maxn];  int b[maxn];  int res[maxn];  int cnt[maxn]; int head[maxn];int pre[maxn<<1];int to[maxn<<1];void add(int x,int y){       to[tote]=y;        pre[tote]=head[x];        head[x]=tote++;    }    bool vis[maxn];    int ans;  //这个dfs为了读取标记信息。 void dfs2(int k){  vis[k]=1;    cnt[k]+=res[k];      for(int i=head[k];~i;i=pre[i]){            int x=to[i];        if(vis[x])continue;dfs2(x);          cnt[k]+=cnt[x];      }      if(k!=1)ans=min(ans,cnt[k]);}   int ff[maxn];int _find(int u){if(ff[u]==u)return u;int res=_find(ff[u]);return res;}void _union(int a,int b){//把a并到b上 int fa=_find(a);int fb=_find(b);ff[a]=b;}//询问有关 const int maxm=200010;int qhead[maxn];int qpre[maxm<<1];int qto[maxm<<1];int totq;void qadd(int x,int y){       qto[totq]=y;        qpre[totq]=qhead[x];        qhead[x]=totq++;    }    bool finish[maxn];//离线LCA void LCA(int u){vis[u]=1;for(int i=head[u];~i;i=pre[i]){int v=to[i];if(vis[v])continue;LCA(v);_union(v,u);}finish[u]=1;//解决关于u的问题。for(int i=qhead[u];~i;i=qpre[i]){int v=qto[i];if(finish[v]){int lca=_find(v);if(u!=lca){                  res[u]++;                  res[lca]--;              }              if(v!=lca){                  res[v]++;                  res[lca]--;              }}} }void init(){    memset(head,-1,sizeof(head));    memset(cnt,0,sizeof(cnt));    memset(res,0,sizeof(res));    memset(finish,0,sizeof(finish));    memset(qhead,-1,sizeof(qhead));    memset(vis,0,sizeof(vis));    tote=0;    totq=0;//for(int i=1;i<=n;i++){ff[i]=i;}}  int main(){          int t;    cin>>t;    int cas=0;    while(t--){        cas++;                cin>>n>>m;  init();        for(int i=1;i<n;i++){              scanf_(a[i]);            scanf_(b[i]);            add(a[i],b[i]);            add(b[i],a[i]);        }                 ans=1000000000;        for(int i=n;i<=m;i++){               int a,b;            scanf_(a);            scanf_(b);            qadd(a,b);            qadd(b,a);        }                          memset(vis,0,sizeof(vis));        LCA(1);memset(vis,0,sizeof(vis));        dfs2(1);          printf("Case #%d: ",cas);        cout<<ans+1<<endl;      }      return 0;  }  

1002 Best Solver

        这题待补。。


0 0
原创粉丝点击