CodeForces Round #293 Div.2

A. Vitaly and Strings

题意:

给出两个长度相同的字符串,问是否存在一个字符串,该串的字典序大于输入的第一个串 且 小于第二个串。

分析:

找出比第一个串大一的串,看看它是否小于第二个串,是的话就满足,否则不存在这样的串。

 1 #include <bits/stdc++.h>

 2 using namespace std;

 3 

 4 const int maxn = 110;

 5 

 6 char s1[maxn], s2[maxn];

 7 

 8 int main()

 9 {

10     //freopen("in.txt", "r", stdin);

11 

12     scanf("%s%s", s1, s2);

13     int l = strlen(s1);

14     int i = l-1;

15     s1[i] += 1;

16     bool flag = false;

17     while(i > 0 && s1[i] > 'z')

18     {

19         s1[i] -= 26;

20         s1[--i] += 1;

21     }

22     if(s1[0] > 'z') { puts("No such string"); return 0; }

23     for(int i = 0; i < l; ++i) if(s1[i] < s2[i]) { flag = true; break; }

24 

25     if(flag) printf("%s\n", s1);

26     else puts("No such string");

27 

28     return 0;

29 }
代码君

 

B. Tanya and Postcard

题意:

从两个字符串中各取一个字符进行匹配,如果两个字符相同,则记作一个YAY,如果仅大小写不同,则记作一个WHOOPS

求在YAY最多的前提下,WHOOPS最多是多少。

分析:

首先扫一遍两个串,统计一下各个字符的个数,先将所有的相同字符进行匹配,这样YAY最多。然后在剩下没有匹配的字符中,找A和a等进行匹配。

 1 #include <bits/stdc++.h>

 2 using namespace std;

 3 

 4 const int maxn = 200000 + 10;

 5 

 6 char s[maxn], t[maxn];

 7 int sum1[256], sum2[256];

 8 

 9 int ID(int x)

10 {

11     if(x < 26) return 'a' + x;

12     return 'A' + x - 26;

13 }

14 

15 int ID2(int x)

16 {

17     if(x < 26) return 'A' + x;

18     return 'a' + x - 26;

19 }

20 

21 int main()

22 {

23     //freopen("in.txt", "r", stdin);

24 

25     scanf("%s%s", s, t);

26     int ls = strlen(s);

27     int lt = strlen(t);

28 

29     for(int i = 0; i < ls; ++i) sum1[s[i]]++;

30     for(int i = 0; i < lt; ++i) sum2[t[i]]++;

31 

32     int yay = 0, whoops = 0;

33 

34     for(int i = 0; i < 52; ++i)

35     {

36         int ind = ID(i);

37         int t = min(sum1[ind], sum2[ind]);

38         yay += t;

39         sum1[ind] -= t; sum2[ind] -= t;

40 

41     }

42 

43     for(int i = 0; i < 52; ++i)

44     {

45         int ind1 = ID(i);

46         int ind2 = ID2(i);

47         int t = min(sum1[ind1], sum2[ind2]);

48         sum1[ind1] -= t; sum2[ind2] -= t;

49         whoops += t;

50     }

51 

52     printf("%d %d\n", yay, whoops);

53 

54     return 0;

55 }
代码君

 

C. Anya and Smartphone (模拟)

题意:

智能手机上有n个APP,每个屏幕恰好放k个APP(最后一个可能放不满)。启动第i页屏幕(编号从1开始)的APP需要操作i个手势,手机还有个特点就是启动完某个APP后会和前面相邻的那个交换位置,启动第一个APP除外。

按顺序给出这些APP的编号,和启动顺序,问总共需要多少个操作手势。

分析:

为了快速计算出每个APP的编号和位置,我们开两个数组 id 和 pos,分别记录 每个位置上APP的编号 和 对应编号APP所在的位置。

在交换的时候,既要交换两个位置对应的id,又要交换两个APP对应id所在的位置。

 1 #include <bits/stdc++.h>

 2 using namespace std;

 3 

 4 const int maxn = 100000 + 10;

 5 

 6 int n, m, k;

 7 long long ans = 0;

 8 

 9 int id[maxn], pos[maxn];

10 

11 int main()

12 {

13     //freopen("in.txt", "r", stdin);

14 

15     scanf("%d%d%d", &n, &m, &k);

16 

17     for(int p = 0; p < n; ++p)

18     {

19         int x;

20         scanf("%d", &x);

21         id[p] = x;

22         pos[x] = p;

23     }

24 

25     for(int i = 0; i < m; ++i)

26     {

27         int x;

28         scanf("%d", &x);

29         int p = pos[x];

30         ans += p / k + 1;

31         if(p == 0) continue;

32         int y = id[p-1];

33         swap(pos[x], pos[y]);//交换位置

34         swap(id[p], id[p-1]);//交换编号

35     }

36 

37     printf("%I64d\n", ans);

38 

39     return 0;

40 }
代码君

 

D. Ilya and Escalator (概率DP)

题意:

有n个人排成一队,每经过一秒会有p的概率队首的那个人乘上电梯,1-p的概率队首的人没有上电梯。这里假设电梯无限长,因此不考虑上电梯的人下来的情况。

问t秒后,电梯人数的期望。

分析:

第一次学会用DP的方法求概率。

设d(i, j)为第i秒后,电梯上有j个人的概率。

初始状态:d(1, 1) = p, d(1, 0) = 1-p

当j == n时,所有的人都已上电梯,则d(i+1, j) += d(i, j)

否则,p的概率上电梯,则有d(i+1, j+1) += d(i, j) * p  

   1-p的概率不上电梯,d(i+1, j) += d(i, j) * (1-p)

最后所求期望就是Σd(t, j) * j (0≤j≤n)

 1 #include <bits/stdc++.h>

 2 using namespace std;

 3 

 4 const int maxn = 2000 + 10;

 5 

 6 double d[maxn][maxn];

 7 

 8 int main()

 9 {

10     int n, t;

11     double p;

12     scanf("%d%lf%d", &n, &p, &t);

13 

14     d[1][1] = p; d[1][0] = 1.0 - p;

15     for(int i = 2; i <= t; i++)

16         for(int j = 0; j <= n; j++)

17         {

18             if(j == n) d[i][j] += d[i-1][j];

19             else

20             {

21                 d[i][j + 1] += d[i-1][j] * p;

22                 d[i][j] += d[i-1][j] * (1.0 - p);

23             }

24         }

25 

26     double ans = 0;

27 

28     for(int i = 0; i <= n; i++) ans += d[t][i] * i;

29 

30     printf("%.8f\n", ans);

31 

32     return 0;

33 }
代码君

 

你可能感兴趣的:(codeforces)