• Codeforces Round #327 (Div2) A~E


    CodeForces 591A

    题意:在距离为L的两端A,B,相向发射魔法,a(以P1的速度)-->B,A<--b(以P2的速度)。假设a-->B,途中相遇,则返回到原点A<--a. 后又继续,a-->B,速度不变。

             b亦是如此。求第二次相遇时a的位移。

    思路:因为速度不变,所以第二次相遇地点与第一次相遇地点一样。

            res= n/(Va+Vb)*Va

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 int main()
     7 {
     8     double n,a,b;
     9     while(cin>>n>>a>>b)
    10         cout<<n/(a+b)*a<<endl;
    11     return 0;
    12 }
    View Code

    CodeForces 591B

    题意:给一个长度为n的字符串s,进行m (1 ≤ n, m ≤ 200 000)次操作。即:s: aba  操作m1:a b 则s变成:bab.求m次变换后的s.

    思路:首先想到的是暴力模拟,但是n,m都是1e5,O(n*m)=1e10,会超时。

            所以需要有技巧的暴力。

            字符串由26个字母组成,每次操作我们只需将字母数组进行操作,保存下字母变换后的字母。最后扫一遍根据字母数组将s改过来就ok了

    注意:处理字母变换后的字母时,每次需先找要变化的值,记录下标,最后再进行交换。

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 char c[30],s[200005];
     7 int n,m;
     8 
     9 int main()
    10 {
    11     for(int i=0;i<26;i++)
    12         c[i]=char('a'+i);
    13     while(~scanf("%d%d",&n,&m))
    14     {
    15 
    16         scanf("%s",s);
    17         char x[2],y[2];
    18         int p1,p2;
    19         for(int i=0;i<m;i++)
    20         {
    21             scanf("%s%s",x,y);
    22             for(int i=0;i<26;i++)
    23             {
    24                 if(c[i]==x[0])
    25                     p1=i;
    26                 if(c[i]==y[0])
    27                     p2=i;
    28             }
    29             c[p1]=y[0];
    30             c[p2]=x[0];
    31         }        
    32         for(int i=0;i<n;i++)
    33             s[i]=c[s[i]-'a'];
    34         printf("%s
    ",s);
    35     }
    36     return 0;
    37 }
    View Code

    CodeForces 590A

    题意:n个数字,只由0、1组成。数字进行01变换。

            变换规则:1、首末数字保持不变B[1]=A[1],B[n]=A[n]

                          2、从左至右,第二个数A[i]开始,B[i]变成(A[i-1],A[i],A[i+1])的中位数

            A->B一直变换,求达到稳定状态,即不能再变的变换次数,并输出最终变换后的B[]数字。

    案例解释:  

           Case 1: 4                              

             0 0 1 1
    A[1-4]={0,0,1,1}
    B[1]=A[1],B[4]=A[4]
    A[1]:0 A[2]:0 A[3]:1 中位数为0,所以B[2]=0
    A[2]:0 A[3]:1 A[4]:1 中位数为!,所以B[3]=1
    B[1-4]={0,0,1,1}
    A==B,所以无法变换

    思路:每次都变换成中位数,最终要求是不变。

           我们可发现连续两个0 0时第二个0不管右边为0还是1,该位都不会改变。1,1同理。

           所以会发现:连续的0 或 连续的1 都是肯定不会变的。

           那么我们可以找到所有连续的0、1,在剩下的数字中进行变换。并且剩下的数字中每个数一定会变,0->1,1->0。

           再仔细一点会发现:最接近连续部分的数进行一次变换后一定会与相邻连续数一样。每个不连续数区间每次变换后不连续数分别从两端各减1;

           因此我们可以根据不连续数长度求变换次数。

           变换次数=max{不连续区间长度}/2+max{不连续区间长度}%2;

                       例如:1 1 0 1 0 1 1 不连续区间长度为3    1 1 0 1 0 1 1 0 1 0 0  最大不连续区间长度=max(3,2)=3

           变更后,可以根据数字所在区间的长度及位置计算变换次数,奇变偶不变。

           因此可转换成一般的模拟题。

    注意:在进行变换的时候要多加注意。

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 using namespace std;
     6 const int maxn=5*1e5+5;
     7 
     8 int b[maxn],c[maxn],n;
     9 
    10 int deal()
    11 {
    12     int maxlen=0,maxx=-1;
    13     int s,e,k;
    14     c[0]=b[0];c[n-1]=b[n-1];
    15     b[n+1]=b[n]=b[n-1];
    16     for(int i=1;i<=n;)
    17     {
    18         if(b[i]==b[i-1])
    19         {
    20             c[i-1]=b[i];k=1;
    21             e=i-2;s=e-maxlen+1;
    22             while(s<e)
    23             {
    24                 c[s]=abs(b[s]-(k%2));
    25                 c[e]=abs(b[e]-(k%2));
    26                 s++;e--,k++;
    27             }
    28             if(s==e)
    29                 c[s]=abs(b[s]-(k%2));
    30         }    
    31         while(i<=n&&b[i]==b[i-1])
    32         {
    33             c[i]=b[i];    
    34             i++;
    35             maxx=max(maxx,maxlen/2+maxlen%2);
    36             maxlen=0;
    37         }
    38         if(i<=n&&b[i]!=b[i+1])
    39             maxlen++;
    40         i++;    
    41     }
    42     return maxx;
    43 }
    44 
    45 int main()
    46 {
    47     while(~scanf("%d",&n))
    48     {
    49         int g=0;
    50         for(int i=0;i<n;i++)
    51             scanf("%d",&b[i]);
    52         printf("%d
    ",deal());
    53         for(int i=0;i<n;i++)
    54             if(g++)
    55                 printf(" %d",c[i]);
    56             else
    57                 printf("%d",c[i]);
    58         printf("
    ");
    59     }
    60     return 0;
    61 }
    View Code

    CodeForces 590B

    题意:一个飞船从起始点(x1,y1)飞向目标点(x2,y2),最大速度为V,方向不定,但是会刮风,风的速度向量在t前为(vx,vy),之后变为(Vx,Vy).现给定相应坐标以及速度大           小,求从起始点飞向目标点最少需要多长时间。

    思路:二分时间。枚举时间tt,求出在tt时间内,风力单独在起始点作用产生的新位置,作为新的起点,再单独求飞船在tt时间内是否能从新起点至目标点。直到找到精度范围内最小         的tt.

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 double x1,y1,x2,y2,t,v,p1,q1,p2,q2;
     7 const double d=0.000001;
     8 
     9 double dis(double x1,double y1,double x2,double y2)
    10 {
    11     return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
    12 }
    13 
    14 bool solve(double tt)
    15 {
    16     double stx,sty;
    17     if(tt<=t)
    18     {
    19         stx=x1+p1*tt;
    20         sty=y1+q1*tt;
    21     }
    22     else
    23     {
    24         stx=x1+p1*t+p2*(tt-t);
    25         sty=y1+q1*t+q2*(tt-t);
    26     }
    27     double distance=dis(stx,sty,x2,y2);
    28     if(distance<=tt*tt*v*v)
    29         return 1;
    30     return 0;
    31 }
    32 
    33 int main()
    34 {
    35     while(~scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2))
    36     {
    37         scanf("%lf%lf%lf%lf%lf%lf",&v,&t,&p1,&q1,&p2,&q2);
    38         double L=0,R=1e8,m;
    39         while((R-L)>d)
    40         {
    41             m=(R+L)/2;
    42             if(solve(m))
    43                 R=m;
    44             else
    45                 L=m;
    46         }
    47         printf("%.18lf
    ",m);
    48     }
    49     return 0;
    50 }
    View Code

    CodeForces 590C

    题意:在n*m的地图上,有三个州“1”,“2”,“3”,每个州是一个整体。除了州,“#”不可开拓道路,“."可开拓道路。求使三个州连通(任一州可到达另一州)最少需要多少个.“

    思路:三个州之间的道路,一定会有一个公共点。所以只需要求每个州到该点的最短路径,进行相加。

            BFS,记录每个州到每个点的最短路径。

    技巧:把所有“1”放入队列后开始搜,同理对“2”,“3”进行一样的操作。

    注意:记录路径的时候,到当位置的路径=到前一位置路径+(前一位置=='.')    最后ans=min(ans,f[0][i][j]+f[1][i][j]+f[2][i][j]+(mp[i][j]=='.'))

            或者按平常的记录方法,ans=min(ans,f[0][i][j]+f[1][i][j]+f[2][i][j]+(mp[i][j]=='.')-2)

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <queue>
     6 using namespace std;
     7 const int maxn=1000+5;
     8 const int inf=1e7;
     9 
    10 int n,m,pre[4][2]={0,1,1,0,0,-1,-1,0};
    11 int f[5][maxn][maxn];
    12 char mp[maxn][maxn];
    13 
    14 struct node 
    15 {
    16     int x,y;
    17 }pos[maxn*maxn];
    18 
    19 void init()
    20 {
    21     for(int i=0;i<3;i++)
    22         for(int j=0;j<n;j++)
    23             for(int k=0;k<m;k++)
    24                 f[i][j][k]=inf;
    25 }
    26 
    27 bool judge(int xx,int yy)
    28 {
    29     if(xx<0||xx>=n||yy<0||yy>=m)
    30         return 0;
    31     return 1;
    32 }
    33 
    34 queue<node> q;
    35 void bfs(int c)
    36 {
    37     char ch=c+'1';
    38     while(!q.empty())
    39         q.pop();
    40 
    41     node a,b;
    42     for(int i=0;i<n;i++)
    43         for(int j=0;j<m;j++)
    44             if(mp[i][j]==ch)
    45             {
    46                 a.x=i;a.y=j;
    47                 q.push(a);
    48                 f[c][i][j]=0;
    49             }
    50     while(!q.empty())
    51     {
    52         a=q.front();
    53         q.pop();
    54         for(int i=0;i<4;i++)
    55         {
    56             int xx=a.x+pre[i][0];
    57             int yy=a.y+pre[i][1];
    58             if(!judge(xx,yy)||mp[xx][yy]=='#')
    59                 continue ;
    60             if(f[c][xx][yy]>f[c][a.x][a.y]+(mp[a.x][a.y]=='.'))
    61             {
    62                 f[c][xx][yy]=f[c][a.x][a.y]+(mp[a.x][a.y]=='.');
    63                 b.x=xx,b.y=yy;q.push(b);
    64             }    
    65         }
    66     }
    67 }
    68 
    69 int deal()
    70 {
    71     int minn=inf;
    72     for(int i=0;i<n;i++)
    73         for(int j=0;j<m;j++)
    74             minn=min(minn,f[0][i][j]+f[1][i][j]+f[2][i][j]+(mp[i][j]=='.'));
    75     return minn;
    76 }
    77 
    78 int main()
    79 {
    80     while(~scanf("%d%d",&n,&m))
    81     {
    82         for(int i=0;i<n;i++)
    83             scanf("%s",mp[i]);
    84         init();
    85         for(int i=0;i<3;i++)
    86             bfs(i);
    87         int mm=deal();
    88         printf("%d
    ",(mm>=inf)?-1:mm);
    89     }
    90     return 0;
    91 }
    View Code
  • 相关阅读:
    php抽象类,接口,特性的比较
    服务器和客户端缓存控制
    git平时用到的仓库
    PHP版DES算法加密数据
    Linux连接Windows服务器以及文件传输方法
    php连接MySQL数据库的三种方式(mysql/mysqli/pdo)
    PHP实现网站访客来访显示访客IP&浏览器&操作系统
    ESXI的使用
    vue
    Laravel学习笔记
  • 原文地址:https://www.cnblogs.com/yang-/p/5528881.html
Copyright © 2020-2023  润新知