【noip2016】d1解题报告

t1:玩具谜题,麻烦的模拟

#include<iostream>
#include<cstdio>
using namespace std;
int n,m,tail=1,a,b;
struct in
{
    int direct;
    char name[20 + 5];
}ter[100010];
/*struct zhiling
{
    int a;
    int b;
}ing[100010];*/

//char tt[100010];

int main()
{
    cin>>n>>m;
    int i,j;
    for(i=1;i<=n;i++)
    {
        scanf("%d", &ter[i].direct);
        scanf("%s", ter[i].name);
    //    ter[i].name = tt;
//        cin>>ter[i].direct>>ter[i].name;
    }
    for(i=1;i<=m;i++)
    {
        cin>>/*ing[i].*/a>>/*ing[i].*/b;
        b=b%n;
        if(ter[tail].direct==0&&a==1)
        {
            /*for(j=b;j>0;j--)
            {
                tail++;
                if(tail==n+1)
                {
                    tail=1;
                }
            }*/
            tail=tail+b;
            if(tail>n)
            {
                tail=tail-n;
            }
            
        }
        else if(ter[tail].direct==0&&a==0)
        {
            /*for(j=b;j>0;j--)
            {
                tail--;
                if(tail==0)
                {
                    tail=n;
                }
            }*/
            tail=tail-b;
            if(tail<=0)
            {
                tail=tail+n;
            }
        }
        else if(ter[tail].direct==1&&a==0)
        {
            tail=tail+b;
            if(tail>n)
            {
                tail=tail-n;
            }
            
        }
        else if(ter[tail].direct==1&&a==1)
        {
            tail=tail-b;
            if(tail<=0)
            {
                tail=tail+n;
            }
        }
        //cout<<ter[tail].name<<endl; 
    }
//    cout<<ter[tail].name; 
    printf("%s\n", ter[tail].name);
    return 0;
}

t2:天天爱跑步……真tm难

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue> 
#include<cmath>
using namespace std;
vector<int>na[600060],ru[600060],to[600060];
int n,m,x,y,z,tail,md,ans[600060],tong[600060],w[600060],val[600060],anto[600060],fa[300030][25],head[300030],de[300030];
struct in
{
    int to,ne;
}ter[600060];
inline void build(int f,int l)
{
    ter[++tail]=(in){l,head[f]},head[f]=tail;
    ter[++tail]=(in){f,head[l]},head[l]=tail;
}
struct es
{
    int f,l,lca,len;
}ing[600060];
void init(int no,int f)
{
    de[no]=de[f]+1;
    md=max(md,de[no]);
    fa[no][0]=f;
    for(int i=head[no];i>0;i=ter[i].ne)
    {
        int t=ter[i].to;
        if(t==f)
            continue;
        init(t,no);
    }
}
inline void make_lca()
{
    for(int i=1;i<=log2(n);i++)
        for(int j=1;j<=n;j++)
            fa[j][i]=fa[fa[j][i-1]][i-1];
}
inline int ask(int x,int y)
{
    if(de[x]<de[y])
        swap(x,y);
    for(int i=log2(n);i>=0;i--)
        if(de[fa[x][i]]>=de[y])
            x=fa[x][i];
    if(x==y)
        return x;
    for(int i=log2(n);i>=0;i--)
        if(fa[x][i]!=fa[y][i])
            x=fa[x][i],y=fa[y][i];
    return fa[x][0];
}
void dfs(int x,int f)
{
    int no=de[x]+w[x],cun;
    if(no<=md)
        cun=tong[no];
    for(int i=head[x];i>0;i=ter[i].ne)
    {
        int t=ter[i].to;
        if(t==f)
            continue;
        dfs(t,x);
    }
    tong[de[x]]+=val[x];
    if(no<=md)
        ans[x]=tong[no]-cun;
    for(int i=0;i<na[x].size();i++)
        tong[de[na[x][i]]]--;
}
void DFS(int x,int f)
{
    int no=de[x]-w[x]+300000;int cun=anto[no];
    for(int i=head[x];i>0;i=ter[i].ne)
    {
        int t=ter[i].to;
        if(t==f)
            continue;
        DFS(t,x);
    }
    for(int i=0;i<ru[x].size();i++)
        anto[ru[x][i]+300000]++;
    ans[x]+=anto[no]-cun;
    for(int i=0;i<to[x].size();i++)
        anto[to[x][i]+300000]--;
}
int main()
{
    memset(head,-1,sizeof(head));
    scanf("%d%d",&n,&m);
    for(int i=1;i<n;i++)
        scanf("%d%d",&x,&y),build(x,y);
    init(1,0);
    make_lca();
    for(int i=1;i<=n;i++)
        scanf("%d",&w[i]);
    for(int i=1;i<=m;i++)
        scanf("%d%d",&x,&y),val[x]++,ing[i].f=x,ing[i].l=y,ing[i].lca=ask(ing[i].f,ing[i].l),ing[i].len=de[ing[i].f]+de[ing[i].l]-2*de[ing[i].lca];
    for(int i=1;i<=m;i++)
        na[ing[i].lca].push_back(ing[i].f);
    dfs(1,0);
    for(int i=1;i<=m;i++)
        ru[ing[i].l].push_back(de[ing[i].l]-ing[i].len);
    for(int i=1;i<=m;i++)
        to[ing[i].lca].push_back(de[ing[i].l]-ing[i].len);
    DFS(1,0); 
    for(int i=1;i<=m;i++)
        if(de[ing[i].f]-de[ing[i].lca]==w[ing[i].lca])
            ans[ing[i].lca]--;
    for(int i=1;i<=n;i++)
        cout<<ans[i]<<' ';
}

t3:换教室,原博客http://www.cnblogs.com/Loi-dfkdsmbd/p/7732020.html

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
int tail,x[2020],y[2020],a,b,c,head[330],n,m,v,e,ans[2020][2020];
double gai[2020],dp[2020][2020][2],pri;
void floyd()//求最短路,预处理 
{
    for(int k=1;k<=v;k++)
        for(int i=1;i<=v;i++)
            for(int j=1;j<=v;j++)
                ans[i][j]=min(ans[i][j],ans[i][k]+ans[j][k]);
}
int main()
{
    scanf("%d%d%d%d",&n,&m,&v,&e);
    for(int i=1;i<=n;i++)
        scanf("%d",&y[i]);
    for(int i=1;i<=n;i++)
        scanf("%d",&x[i]);
    for(int i=1;i<=n;i++)
        scanf("%lf",&gai[i]);
    memset(ans,0x3f,sizeof(ans));
    for(int i=1;i<=v;i++)
        ans[i][i]=0;
    for(int i=1;i<=e;i++)
        scanf("%d%d%d",&a,&b,&c),ans[a][b]=ans[b][a]=min(c,ans[b][a]);
    floyd();
    memset(dp,127,sizeof(dp));
    dp[0][0][0]=dp[1][0][0]=dp[1][1][1]=0;//初始化,一定要记得把dp[1][1][1]赋值为0!!! 
    for(int i=2;i<=n;i++)//一个点都不申请的时候 
        dp[i][0][0]=ans[y[i-1]][y[i]]+dp[i-1][0][0];
    for(int i=2;i<=n;i++)
        for(int j=1;j<=min(m,i);j++)
        {
            dp[i][j][0]=min(dp[i-1][j][0]+ans[y[i-1]][y[i]],dp[i][j][0]);//当这个点不取的时候很简单,就看上一个点是否备取就行 
            dp[i][j][0]=min(dp[i-1][j][1]+(ans[x[i-1]][y[i]]*gai[i-1]+ans[y[i-1]][y[i]]*(1-gai[i-1])),dp[i][j][0]);
            dp[i][j][1]=min(dp[i][j][1],dp[i-1][j-1][0]+(ans[y[i-1]][x[i]]*gai[i]+ans[y[i-1]][y[i]]*(1-gai[i])));//当这个点取的时候,要考虑四种情况,a取/不取 b取/不取 
            dp[i][j][1]=min(dp[i][j][1],dp[i-1][j-1][1]+
                        ans[x[i-1]][x[i]]*gai[i-1]*gai[i]
                       +ans[x[i-1]][y[i]]*gai[i-1]*(1-gai[i])
                       +ans[y[i-1]][x[i]]*gai[i]*(1-gai[i-1])
                       +ans[y[i-1]][y[i]]*(1-gai[i])*(1-gai[i-1]));
        }
    pri=dp[n][0][0];
    for(int i=1;i<=m;i++)//取个最小值 
        pri=min(pri,min(dp[n][i][0],dp[n][i][1]));
    printf("%.2lf",pri);
}

 

posted @ 2017-11-10 07:31  那一抹落日的橙  阅读(219)  评论(0编辑  收藏  举报