noip2014题解

没有正解 都是我的暴力

T1生活大爆炸版石头剪刀布

把得分要求存进C数组里

c[i][j]表示i对j的得分情况

#include<iostream>
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define LL long long
#define N 202
using namespace std;

int n,na,nb;

int a[N],b[N],c[10][10];

int A,B;

void rule_()
{
    /*
    0--剪刀 1--石头 2--布  3--蜥蜴人  4--斯波克 
    */
    for(int i=0;i<=4;i++) c[i][i]=0;
    c[0][1]=0;c[0][2]=1;c[0][3]=1;c[0][4]=0;
    c[1][0]=1;c[1][2]=0;c[1][3]=1;c[1][4]=0;
    c[2][0]=0;c[2][1]=1;c[2][3]=0;c[2][4]=1;
    c[3][0]=0;c[3][1]=0;c[3][2]=1;c[3][4]=1;
    c[4][0]=1;c[4][1]=1;c[4][2]=0;c[4][3]=0;
}

void play_()
{
    for(int i=1;i<=n;i++)
    {
        int xa,xb;
        xa=i%na;if(!xa) xa=na;
        xb=i%nb;if(!xb) xb=nb;
        A=A+c[a[xa]][b[xb]];
        B=B+c[b[xb]][a[xa]]; 
    }
}

int main()
{
///    freopen("rps.in","r",stdin);
///    freopen("rps.out","w",stdout);
    scanf("%d%d%d",&n,&na,&nb);
    for(int i=1;i<=na;i++) scanf("%d",&a[i]);
    for(int i=1;i<=nb;i++) scanf("%d",&b[i]);
    rule_();
    play_();
    printf("%d %d
",A,B);
//    fclose(stdin);
//    fclose(stdout);
    return 0;
}
/*
10 5 6
0 1 2 3 4
0 3 4 2 1 0

9 5 5
0 1 2 3 4
1 0 3 2 4
*/
100

T2联合权值

30% O(n^3)floyed求两点距离+n^2枚举

60% LCA求两点距离+n^2枚举

#include<iostream>
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define LL long long
#define N 2020
#define M 10007
using namespace std;

int n;

int sumedge;

int head[N],w[N];

int size[N],deep[N],dad[N],top[N];

int dis[103][103];

inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

struct Edge
{
    int x,y,nxt;
    Edge(int x=0,int y=0,int nxt=0):
        x(x),y(y),nxt(nxt){}
}edge[N<<1];

void add(int x,int y)
{
    edge[++sumedge]=Edge(x,y,head[x]);
    head[x]=sumedge;
}

void slove1()
{
    int max_,res;max_=res=0;
    memset(dis,0x3f,sizeof(dis));
    for(int i=1;i<=n;i++) dis[i][i]=0;
    for(int i=1;i<n;i++)
    {
        int x,y;
        x=read();y=read();
        dis[x][y]=dis[y][x]=1;
    }
    for(int k=1;k<=n;k++)
     for(int i=1;i<=n;i++)
      for(int j=1;j<=n;j++)
       dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
    for(int i=1;i<=n;i++) w[i]=read();
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
    //        cout<<i<<" "<<j<<" "<<dis[i][j]<<endl;
            if(dis[i][j]!=2) continue;
    //        cout<<i<<" --- "<<j<<endl;
            int tmp;tmp=w[i]*w[j];
            max_=max(max_,tmp);
            res=(res%M+tmp%M)%M;
        }
    }
    printf("%d %d
",max_,res);
}

void dfs(int x)
{
    size[x]=1;deep[x]=deep[dad[x]]+1;
    for(int i=head[x];i;i=edge[i].nxt)
    {
        int v=edge[i].y;
        if(v==dad[x]) continue;
        dad[v]=x;
        dfs(v);
        size[x]+=size[v];
    }
}

void dfs_(int x)
{
    int s=0;
    if(!top[x]) top[x]=x;
    for(int i=head[x];i;i=edge[i].nxt)
    {
        int v=edge[i].y;
        if(v!=dad[x]&&size[v]>size[s]) s=v;
    }
    if(s)
    {
        top[s]=top[x];
        dfs_(s);
    }
    for(int i=head[x];i;i=edge[i].nxt)
    {
        int v=edge[i].y;
        if(v!=dad[x]&&v!=s)dfs_(v);
    }
}

int LCA(int x,int y)
{
    if(deep[x]>deep[y]) swap(x,y);
    for(;top[x]!=top[y];)
    {
        if(deep[top[x]]>deep[top[y]]) swap(x,y);
        y=dad[top[y]];
    }
    if(deep[x]>deep[y]) swap(x,y);
    return x; 
}

void slove2()
{
    int max_,res;max_=res=0;
    for(int i=1;i<n;i++)
    {
        int x,y;
        x=read();y=read();
        add(x,y);add(y,x);
    }
    for(int i=1;i<=n;i++) w[i]=read();
    deep[0]=-1;
    dfs(1);dfs_(1);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            int D,tmp;D=deep[i]+deep[j]-2*deep[LCA(i,j)];
            if(D!=2) continue;tmp=w[i]*w[j];    
            max_=max(max_,tmp);
            res=(res%M+tmp%M)%M;
        }
    }
    printf("%d %d
",max_,res);
}

int main()
{
//    freopen("linkb.in","r",stdin);
//    freopen("linkb.out","w",stdout);
    n=read();
    if(n<=100) slove1();
    else 
    if(n<=2000) 
    slove2();
//    fclose(stdin);
//    fclose(stdout);
    return 0;
}
/*
5
1 2
2 3
3 4 
4 5
1 5 2 3 10

4
1 2
2 3
2 4
1 1 1 1
*/
60

 T3飞扬的小鸟

加卡时35不加30....

#include<iostream>
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define LL long long
#define N 10005
using namespace std;

int n,m,k,js;

int ans_z,ans_c;

int X[N],Y[N];

bool bo[N]; 

struct A
{
    int x,l,r;
}a[N];

struct B
{
    int l,r;
}b[N];

bool cmp(A a,A b)
{
    return a.x<b.x;    
}

void dfs(int x,int y,int c,int z)
{
/*    if(++js>400000)
    {
       if(ans_c==k)
        {
        printf("1
");
        printf("%d
",ans_z);
        }else
        {
        printf("0
");
        printf("%d
",ans_c);
       }
      // fclose(stdin);fclose(stdout);
       exit(0);
    }*/
    ans_c=max(ans_c,c);//更新通过的最多的管子数 
    if(x==n)                 //已经到达终点 
    {
        ans_z=min(ans_z,z);
        return ;
    }
    if(bo[x+1])
    {
        int nxty;nxty=y-Y[x];
        if(nxty>b[x+1].l&&nxty<b[x+1].r) dfs(x+1,nxty,c+1,z);
        for(int i=1;i<=3;i++)
        {
            int nxty;nxty=y+X[x]*i;
            if(nxty>b[x+1].l&&nxty<b[x+1].r) dfs(x+1,nxty,c+1,z+i);
        }
    } 
    if(!bo[x+1])
    {
        int nxty;nxty=y-Y[x];
        if(nxty>0) dfs(x+1,nxty,c,z);
        for(int i=1;i<=3;i++)
        {
            int nxty;nxty=y+X[x]*i;
            dfs(x+1,min(nxty,m),c,z+i);
        }
    }
    return ;
}


int main()
{
//    freopen("birda.in","r",stdin);
//    freopen("birda.out","w",stdout); 
    scanf("%d%d%d",&n,&m,&k);/*长、高、水管数量 */
    for(int i=0;i<n;i++) scanf("%d%d",&X[i],&Y[i]);/*在位置i点击屏幕后上升的高度和不点击之后下降的高度*/
    for(int i=1;i<=k;i++) scanf("%d%d%d",&a[i].x,&a[i].l,&a[i].r),bo[a[i].x]=true;
    for(int i=1;i<=k;i++) b[a[i].x].l=a[i].l,b[a[i].x].r=a[i].r;
    ans_z=n*m;
    for(int i=1;i<=m;i++) dfs(0,i,0,0);
    //目前坐标为(0,i),通过的管道数,目前点击了屏幕的数量 
    if(ans_c==k)
    {
        printf("1
");
        printf("%d
",ans_z);
    }else
    {
        printf("0
");
        printf("%d
",ans_c);
    }
//    fclose(stdin);fclose(stdout);
    return 0;
}
/*
10 10 6
3 9
9 9
1 2
1 3
1 2
1 1
2 1
2 1
1 6
2 2
1 2 7
5 1 5
6 3 5
7 5 8
8 7 9
9 1 3
*/
30/35
原文地址:https://www.cnblogs.com/zzyh/p/9918087.html