zoukankan      html  css  js  c++  java
  • CH Round #58

    A:颜色问题

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题

    题解:算一下每个仆人到它的目的地的时间取max即可

    代码:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 1000000000
    13 #define maxn 1500000
    14 #define maxm 500+100
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,int>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
    22 #define mod 1000000007
    23 using namespace std;
    24 inline int read()
    25 {
    26     int x=0,f=1;char ch=getchar();
    27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    29     return x*f;
    30 }
    31 int n,f[maxn],head[maxn];
    32 struct edge{int go,next;}e[maxn];
    33 int main()
    34 {
    35     freopen("input.txt","r",stdin);
    36     freopen("output.txt","w",stdout);
    37     n=read();
    38     for1(i,n)
    39     {
    40         int x=read();
    41         e[i].go=i;e[i].next=head[x];head[x]=i;
    42         f[i]=inf;
    43     }
    44     for1(i,n)
    45     {
    46         int x=read();
    47         for(int j=head[x];j;j=e[j].next)
    48          {
    49              int y=e[j].go;
    50              if(y>=i)f[y]=min(f[y],y-i+1);else f[y]=min(f[y],n-i+y+1);
    51          }
    52     }
    53     int ans=1;
    54     for1(i,n)ans=max(ans,f[e[i].go]);
    55     printf("%d
    ",ans==inf?-1:ans);
    56     return 0;
    57 }
    View Code

    B:树的问题

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/树的问题

    题解:如果x和y的LCA不是其中任意一个,那么答案显然是s[x]+s[y],画一下图就知道

            否则不妨设LCA(x,y)=x,则ans=n-(s[son[x]]-s[y]) 其中son[x]是 x 走向 y的第一个点,画一下图就可以知道。。。

             而son[x]不能dfs求,只要把y倍增上去即可。需要思考一下。

           具体看代码

    代码:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 1000000000
    13 #define maxn 300000
    14 #define maxm 500+100
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,int>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
    22 #define mod 1000000007
    23 using namespace std;
    24 inline int read()
    25 {
    26     int x=0,f=1;char ch=getchar();
    27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    29     return x*f;
    30 }
    31 int n,m,head[maxn],tot,fa[maxn],s[maxn],f[maxn][25],dep[maxn];
    32 struct edge{int go,next;}e[2*maxn];
    33 inline void insert(int x,int y)
    34 {
    35     e[++tot].go=y;e[tot].next=head[x];head[x]=tot;
    36     e[++tot].go=x;e[tot].next=head[y];head[y]=tot;
    37 }
    38 void dfs(int x)
    39 {
    40     s[x]=1;
    41     for1(i,20)
    42      if((1<<i)<=dep[x])f[x][i]=f[f[x][i-1]][i-1];
    43      else break;
    44     for(int i=head[x],y;i;i=e[i].next)
    45      if(!dep[y=e[i].go])
    46       {
    47           dep[y]=dep[x]+1;
    48           f[y][0]=x;
    49           dfs(y);
    50           s[x]+=s[y];
    51       }
    52 }
    53 bool lca(int x,int y)
    54 {
    55     int ans=0;
    56     if(dep[x]<dep[y])swap(x,y);
    57     int t=dep[x]-dep[y];
    58     for0(i,20)
    59      if(t&(1<<i))x=f[x][i];
    60     return x==y;  
    61 }
    62 int main()
    63 {
    64     freopen("input.txt","r",stdin);
    65     freopen("output.txt","w",stdout);
    66     n=read();m=read();
    67     for1(i,n-1)insert(read(),read());
    68     dep[1]=1;
    69     dfs(1);
    70     while(m--)
    71     {
    72         int x=read(),y=read();
    73         if(dep[x]>dep[y])swap(x,y);
    74         if(!lca(x,y))printf("%d
    ",s[x]+s[y]);
    75         else 
    76          {
    77             int t=dep[y]-dep[x]-1,w=y;
    78             for0(i,20)if(t&(1<<i))w=f[w][i];
    79             printf("%d
    ",n-(s[w]-s[y]));
    80          }
    81     }
    82     return 0;
    83 }
    View Code

    C:比赛问题

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/比赛问题

    题解:刚开始把题看简单了,直接一个n*m*k*k的DP。。。还感叹怎么这么水。。。

            后来发现这k*k个方格的状态是有后效性的T_T

            然后发现好像可以状压得70,但我感觉我写不出来或者写出来调不出来,然后就交了错误的程序弃疗了。。。

           最后居然有40QAQ

    代码:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 1000000000
    13 #define maxn 150
    14 #define maxm 500+100
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,int>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
    22 #define mod 1000000007
    23 using namespace std;
    24 inline int read()
    25 {
    26     int x=0,f=1;char ch=getchar();
    27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    29     return x*f;
    30 }
    31 int n,m,k,x,y,xx,yy,f[maxn][maxn];
    32 bool a[maxn][maxn],b[maxn][maxn];
    33 int main()
    34 {
    35     freopen("input.txt","r",stdin);
    36     freopen("output.txt","w",stdout);
    37     n=read();m=read();k=read();x=read();y=read();xx=read();yy=read();
    38     for1(i,k)for1(j,k)
    39     {
    40         char ch=' ';
    41         while(ch!='0'&&ch!='1')ch=getchar();
    42         a[i][j]=ch=='1';
    43     }
    44     for1(i,n)for1(j,m)
    45     {
    46         char ch=' ';
    47         while(ch!='B'&&ch!='W')ch=getchar();
    48         b[i][j]=ch=='W';
    49     }
    50     memset(f,60,sizeof(f));
    51     f[x][y]=0;
    52     for1(i,k)
    53      for1(j,k)
    54       if(a[i][j]&&b[x+i-1][y+j-1])f[x][y]++;
    55     for2(i,x,xx)
    56      for2(j,y,yy)
    57       if(i!=x||j!=y)
    58        {
    59            int tmp=0;
    60            for1(ii,k-1) 
    61             for1(jj,k)
    62              if(a[ii][jj]&&!a[ii+1][jj]&&b[i+ii-1][j+jj-1])tmp++;
    63         for1(jj,k)if(a[k][jj]&&b[i+k-1][j+jj-1])tmp++;
    64            f[i][j]=min(f[i][j],f[i-1][j]+tmp);
    65            tmp=0;
    66            for1(ii,k)
    67             for1(jj,k-1)
    68              if(a[ii][jj]&&!a[ii][jj+1]&&b[i+ii-1][j+jj-1])tmp++;
    69            for1(ii,k)if(a[ii][k]&&b[i+ii-1][j+k-1])tmp++;
    70            f[i][j]=min(f[i][j],f[i][j-1]+tmp);
    71         //cout<<i<<' '<<j<<' '<<f[i][j]<<endl;
    72        }
    73     printf("%d
    ",f[xx][yy]);       
    74     return 0;
    75 }
    View Code
  • 相关阅读:
    [ZJOJ] 5772【NOIP2008模拟】今天你AK了吗
    exgcd扩展欧几里得求解的个数
    Dinic当前弧优化 模板及教程
    [Luogu] P3907 圈的异或
    提升——树形DP
    C++ 优先队列
    C++ 洛谷 P2458 [SDOI2006]保安站岗 from_树形DP
    C++ 洛谷 2014 选课 from_树形DP
    C++ luogu1352没有上司的舞会 from_树形DP
    浅说——树形DP
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4051840.html
Copyright © 2011-2022 走看看