NVCPC preview contest from Tailmon

来源:互联网 发布:淘宝黑搜20单五天必爆 编辑:程序博客网 时间:2024/05/17 17:18

overview

Tailmon’s Multiple 30

算法如图,显而易见。要特判各位数相加为0的情况。

#include<iostream>#include<string>#include<algorithm>int main(){    std::string s;    std::cin>>s;    std::sort(s.begin(),s.end(),std::greater<char>());    int sum=0;    for(int i=0; i!=s.size(); ++i)        sum+=s[i]-'0';    std::cout<<(sum&&sum%3==0&&s.back()=='0'?                s:"-1")<<'\n';}                               

Tailmon’s Fibnacci Sequence

#include<iostream>int main(){    long long n,a=0,b=1,c,sum=1;    std::cin>>n;    while(--n)    {        c=b;        sum+=b+=a;        b%=1000000007;        sum%=1000000007;        a=c;    }    std::cout<<sum<<'\n';}                                 

Tailmon’s Evolution

题面没有说明的是,无论输入单词间有多少空格间隔,输出时统一按一个,结尾也要空格。

#include<iostream>#include<string>using namespace std;int main(){    for(string s;cin>>s;)        cout<<((s!="tailmon")?s:"angewomon")<<' ';    cout<<'\n'; }                                 

Tailmon with God Ye

判断是否要对时间最长的任务上标签。

#include<iostream>int main(){    int n,sum=0,g=0;    std::cin>>n;    for(int i=0,t;i!=n;++i)    {        std::cin>>t;        sum+=t;        if(g<t)g=t;    }    if(g>2)sum-=g-2;    std::cout<<sum<<'\n';}                                 

Tailmon Compares Numbers

#include<iostream>#include<string>bool less(const std::string &s0,          const std::string &s1){    if(s0.size()!=s1.size())return s0.size()<s1.size();    for(int i=0; i!=s0.size(); ++i)        if(s0[i]!=s1[i])            return s0[i]<s1[i];    return 0;}int main(){    std::string s[2];    for(int i=0,pos; i!=2; ++i)    {        std::cin>>s[i];        for(pos=0;                pos!=s[i].size()&&                s[i][pos]=='0';                ++pos);        s[i]=s[i].substr(pos);    }    std::cout<<(less(s[0],s[1])?'<':                less(s[1],s[0])?'>':'=')             <<'\n';}                                 

Tailmon Wants to Make a Big News

#include<iostream>int work(int n){    static int f[64]={0,1,2,0};    if(f[n])return f[n];    return f[n]=work(n-1)+work(n-2);}int main(){    int n;    std::cin>>n;    std::cout<<work(n)<<'\n';}                                 

Tailmon on a Chessboard

卡cin读入,换C做这题。

#include<stdio.h>char chess[102][10002]= {0};int n,m,q,t,x,y,pos[101]= {0};int main(){    scanf("%d%d%d",&n,&m,&q);    for(int i=1; (pos[i]=i)<=n; ++i)        for(int j=1; j<=m; ++j)            chess[i][j]='.';    while(q--)    {        scanf("%d",&t);        if(t==1)        {            scanf("%d%d%d",&t,&x,&y);            chess[pos[x]][y]=(t==1?'w':'b');        }        else if(t==2)        {            scanf("%d%d",&x,&y);            t=pos[x];            pos[x]=pos[y];            pos[y]=t;        }    }    for(int i=1; i<=n; ++i)        printf("%s\n",chess[pos[i]]+1);}                                 

Tailmon Found Hakurei Shrine

对于询问的每个点,既然没有摧毁并且不能到达源点,那么与它们相邻的每个点一定不可以到达(反证:如果可以到达,那么询问点只需到达该点就可转至源点,与题意矛盾;前提:地震前所有点都连通)。于是强行摧毁所有与询问点联通且非询问点的点,便得到最优解。
出题人良心,凭借上述算法过不了第二个样例。原因是当上述点被摧毁后,又有新的点无法到达源点(样例中的9号点)。于是从源点DFS并避开所有询问点和摧毁点,此次DFS中没有访问到的点总数就是所求答案。

#include<iostream>#include<vector>using namespace std;struct Edge{    int from,to;}e_tmp;struct Graph:vector<Edge>{    int n;    vector<vector<int> > a;    void to_list(int _n)    {        n=_n;        a.assign(n,vector<int>());        for(iterator i=begin(); i!=end(); ++i)            a[i->from].push_back(i-begin());    }}g;int m,k,ans=0;bool flag[30001]={0},vis[30001]={0}; void dfs(int k){    if(flag[k]||vis[k])return;    vis[k]=1;    for(int i=0;i!=g.a[k].size();++i)        dfs(g[g.a[k][i]].to);}int main(){    cin>>g.n>>m>>k;    while(m--)    {        cin>>e_tmp.from>>e_tmp.to;        g.push_back(e_tmp);        swap(e_tmp.from,e_tmp.to);        g.push_back(e_tmp);    }    g.to_list(++g.n);    while(k--)    {        cin>>m;        flag[m]=1;        for(int i=0;i!=g.a[m].size();++i)            flag[g[g.a[m][i]].to]=1;    }    dfs(1);    for(int i=1;i!=g.n;++i)        if(flag[i]||!vis[i])            ++ans;    cout<<ans<<'\n';}                                 

Tailmon %%%YSX

线段树,每个节点维护五个区间,存六个数…只能过样例。

#include<iostream>#include<vector>using namespace std;struct SegTree1{    vector<long long> addv;    vector<int> ldown,rup,lman,rman,man_l,man_r;//最左/右下降/上升/人字形区间的另一端点;最优人字形的左右端点    explicit SegTree1(int n)://有效下标1~n,0作逻辑用处        addv(2*n,0),        ldown(2*n,0),        rup(2*n,0),        lman(2*n,0),        rman(2*n,0),        man_l(2*n,0),        man_r(2*n,0) {}    void add(int pl,int pr,long long pv,//效率O((logN)^2)             int k,int l,int r)    {        if(pl<=l&&r<=pr)addv[k]+=pv;        else        {            int lc=k*2,rc=k*2+1,m=l+(r-l)/2;            if(pl<=m)add(pl,pr,pv,lc,l,m);            if(m<pr)add(pl,pr,pv,rc,m+1,r);        }        maintain(k,l,r);    }    long long get(int p,int k,int l,int r)//效率O(logN)    {        if(l==r)return addv[k];        int lc=k*2,rc=k*2+1,m=l+(r-l)/2;        return addv[k]+(p<=m?                        get(p,lc,l,m):                        get(p,rc,m+1,r));    }    void maintain(int k,int l,int r)//维护节点k    {        if(l==r)        {            ldown[k]=rup[k]=lman[k]=rman[k]=man_l[k]=man_r[k]=r;            return;        }        int lc=k*2,rc=k*2+1,m=l+(r-l)/2;        long long hm=get(m,k,l,r),hn=get(m+1,k,l,r);        //维护区间k含左端点的最长连续下降区间的另外一个端点        ldown[k]=ldown[lc];        if(ldown[k]==m&&hm>hn)            ldown[k]=ldown[rc];        //维护区间k含右端点的最长连续上升区间的另外一个端点        rup[k]=rup[rc];        if(rup[rc]==m+1&&hm<hn)            rup[k]=rup[lc];        //维护区间k含左端点的最长人字形的区间        lman[k]=lman[lc];        if(lman[k]==m&&hm>hn)            lman[k]=ldown[rc];        if(hm<hn&&rup[lc]==l)//顶点在右侧并向左延伸,左区间全升            if(lman[k]<lman[rc])                lman[k]=lman[rc];        //维护区间k含右端点的最长人字形的区间        rman[k]=rman[rc];        if(rman[k]==m+1&&hm<hn)            rman[k]=rup[lc];        if(hm>hn&&ldown[rc]==r)//顶点在左侧并向右延伸,右区间全降            if(rman[k]>rman[lc])                rman[k]=rman[lc];        //维护本区间最优人字形区间(可能不唯一)        man_l[k]=man_l[lc],man_r[k]=man_r[lc];        if(man_r[k]-man_l[k]<man_r[rc]-man_l[rc])            man_l[k]=man_l[rc],man_r[k]=man_r[rc];        //包含左右端点的区间        if(man_r[k]-man_l[k]<lman[k]-l)            man_l[k]=l,man_r[k]=lman[k];        if(man_r[k]-man_l[k]<r-rman[k])            man_l[k]=rman[k],man_r[k]=r;        //顶点在左区间并且可扩展至右区间        if(hm>hn)            if(man_r[k]-man_l[k]<ldown[rc]-rman[lc])                man_l[k]=rman[lc],man_r[k]=ldown[rc];        //顶点在右区间并且可扩展至左区间        if(hm<hn)            if(man_r[k]-man_l[k]<lman[rc]-rup[lc])                man_l[k]=rup[lc],man_r[k]=lman[rc];    }};int main(){    int n,m;    cin>>n>>m;    SegTree1 teemo(n);    for(int i=1,t; i<=n; ++i)    {        cin>>t;        teemo.add(i,i,t,1,1,n);    }    for(int i=1,l,r,d; i<=m; ++i)    {        cin>>l>>r>>d;        teemo.add(l,r,d,1,1,n);        cout<<teemo.man_r[1]-teemo.man_l[1]+1<<'\n';    }}
阅读全文
1 0
原创粉丝点击