Codeforces Round #327 (Div2)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #327 (Div2)相关的知识,希望对你有一定的参考价值。

 

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\\n",s);
35     }
36     return 0;
37 }
View Code

 

CodeForces 590A

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

        变换规则: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\\n",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("\\n");
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\\n",m);
48     }
49     return 0;
50 }
View Code

 

以上是关于Codeforces Round #327 (Div2)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #327 (Div. 2)-Wizards' Duel

随笔—邀请赛前训—Codeforces Round #327 (Div. 2) Rebranding

Codeforces Round #191 (Div. 2) A. Flipping Game

Codeforces Round #436 E. Fire(背包dp+输出路径)

[ACM]Codeforces Round #534 (Div. 2)

Codeforces_327_C