• Codeforces Round #301 (Div. 2)


    A. Combination Lock

      题意:有一个数字锁,共有n圈。给出初始状态和密码,求最小需要转动多少次。

      思路:对于每一圈,选取min(dis,10-dis)

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 using namespace std;
     5 char s1[1010], s2[1010];
     6 int main()
     7 {
     8     int n;
     9     scanf("%d", &n);
    10     scanf("%s%s", s1, s2);
    11     int ans = 0;
    12     for (int i = 0; i < n; i++)
    13     {
    14         int n1 = s1[i] - '0';
    15         int n2 = s2[i] - '0';
    16         int dis = abs(n1 - n2);
    17         ans += min(dis, 10 - dis);
    18     }
    19     printf("%d
    ", ans);
    20     return 0;
    21 }
    View Code

    B. School Marks

      题意:Vova 需要做n个测试,每个测试得分可以从1至p.现在他已经做了k张测试,他想要所有测试成绩之和不超过x,同时测试成绩的中位数不低于y.若有该方案,输出剩余测试应当得分为多少。

      思路:如果当前已有分数和+n-k>x或者已有分数小于y的个数>n/2或者在满足y(比y小的补1,其余补y)时不满足x时,则无解。

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 int nm[1010];
     5 int main()
     6 {
     7     int n, k, p, x, y;
     8     scanf("%d%d%d%d%d", &n, &k, &p, &x, &y);
     9     int tot = 0;
    10     int nlownm = 0,lownm=0;
    11     for (int i = 0; i < k; i++)
    12     {
    13         scanf("%d", nm + i);
    14         tot += nm[i];
    15         if (nm[i] >= y) nlownm++;
    16         else lownm++;
    17     }
    18     if (tot + n - k > x||lownm>n/2) printf("-1
    ");
    19     else
    20     {
    21         int re = n - k;
    22         int rev = x - tot;
    23         if (nlownm <= n / 2 + 1 && rev < (n / 2 + 1 - nlownm)*y + n / 2 - lownm) printf("-1
    ");
    24         else
    25         {
    26             while (nlownm < n / 2 + 1)
    27             {
    28                 nm[k++] = y;
    29                 nlownm++;
    30             }
    31             while (k < n) nm[k++] = 1;
    32             for (int i = re; i >=1; --i)
    33             {
    34                 printf("%d", nm[k-i]);
    35                 if (i>1) printf(" ");
    36             }
    37             printf("
    ");
    38         }
    39     }
    40     return 0;
    41 }
    View Code

    C. Ice Cave

      题意:有个n*m的冰块,格子为‘.’表示此处冰块完整,为'X'表示冰块破碎。如果走到一处完整的冰块,其会破碎,走到破碎的冰块上,冰块会裂掉且你会掉下去。问能够从目的冰块格子落下?

      思路:如果存在从起点到终点的路径,如果终点为破碎冰块或者为完整冰块且附近至少有2块完整冰块(当起点和终点为隔壁冰块时,只需要1块其他邻近完整冰块)时,则成功;否则失败。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 using namespace std;
     5 char mp[510][510];
     6 bool vis[510][510];
     7 int tag_r, tag_c;
     8 int st_r, st_c;
     9 int dr[] = { 0,0,1,-1 };
    10 int dc[] = { 1,-1,0,0 };
    11 int n, m;
    12 bool DFS(int r, int c)
    13 {
    14     for (int i = 0; i < 4; i++)
    15     {
    16         int tr = r + dr[i], tc = c + dc[i];
    17         if (tr >= n || tr < 0 || tc >= m || tc < 0) continue;
    18         if (tr == tag_r && tc == tag_c) return true;
    19         else if(mp[tr][tc]=='.'&&!vis[tr][tc])
    20         {
    21             vis[tr][tc] = true;
    22             mp[tr][tc] = 'X';
    23             bool flag=DFS(tr, tc);
    24             mp[tr][tc] = '.';
    25             if (flag) return true;
    26         }
    27     }
    28     return false;
    29 }
    30 int main()
    31 {
    32     scanf("%d%d", &n, &m);
    33     for (int i = 0; i < n; i++) scanf("%s", mp + i);
    34     scanf("%d%d%d%d", &st_r, &st_c, &tag_r, &tag_c);
    35     st_r--, st_c--, tag_r--, tag_c--;
    36     int cnt = 0;
    37     for (int i = 0; i < 4; i++)
    38     {
    39         int tr = tag_r + dr[i], tc = tag_c + dc[i];
    40         if (tr >= n || tr < 0 || tc >= m || tc < 0) continue;
    41         if (mp[tr][tc]=='.') cnt++;
    42     }
    43     bool ok = DFS(st_r, st_c);
    44     if (ok)
    45     {
    46         if (mp[tag_r][tag_c] == 'X')    printf("YES
    ");
    47         else if (cnt >= 2||((abs(tag_r - st_r) + abs(tag_c - st_c) == 1)&&cnt)) printf("YES
    ");
    48         else printf("NO
    ");
    49     }
    50     else printf("NO
    ");
    51     return 0;
    52 }
    View Code

     D. Bad Luck Island

      题意:石头怪、剪刀怪、布怪各有r,s,p个,每两个怪物遇到的几率相同。相遇时,石头怪会杀掉剪刀怪,剪刀怪会杀掉布怪,布怪会杀掉石头怪。经过很长一段时间后,求3中怪物最后只剩其自己一种怪物的几率各是多少?

      思路:假设当前有tr个石头怪,ts个剪刀怪,tp个布怪,那么不同种类的相遇可能数有tr*ts+ts*tp+tp*tr种,对于石头怪,其遇到天敌布怪的几率为tp*tr/(tr*ts+ts*tp+tp*tr),则rate[tr-1][ts][tp]+=rate[tr][ts][tp]*tp*tr/(tr*ts+ts*tp+tp*tr).

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 double rr[110][110][110];
     5 int main()
     6 {
     7     int r, s, p;
     8     scanf("%d%d%d", &r, &s, &p);
     9     rr[r][s][p] = 1.0;
    10     for (int tr = r; tr >= 0; --tr)
    11     {
    12         for (int ts = s; ts >= 0; --ts)
    13         {
    14             for (int tp = p; tp >= 0; --tp)
    15             {
    16                 int tot = tr * ts + tr * tp + ts * tp;
    17                 if (tot == 0) continue;
    18                 if (tr) rr[tr - 1][ts][tp] += rr[tr][ts][tp] * 1.0*tr*tp / tot;
    19                 if (ts) rr[tr][ts - 1][tp] += rr[tr][ts][tp] * 1.0*ts*tr / tot;
    20                 if (tp) rr[tr][ts][tp - 1] += rr[tr][ts][tp] * 1.0*tp*ts / tot;
    21             }
    22         }
    23     }
    24     double ans_r = 0, ans_s = 0, ans_p = 0;
    25     for (int i = 1; i <= r; i++) ans_r += rr[i][0][0];
    26     for (int i = 1; i <= s; i++) ans_s += rr[0][i][0];
    27     for (int i = 1; i <= p; i++) ans_p += rr[0][0][i];
    28     printf("%.12lf %.12lf %.12lf
    ", ans_r, ans_s, ans_p);
    29     return 0;
    30 }
    View Code

     E. Infinite Inversions

      题意:在一个1,2,3,4,5,...序列中,进行n次交换,求逆序对数?

      思路:因为数值很大,对所有数进行离散化;采用树状数组进行求解逆序对,按照顺序插入树状数组,更新值为1.注意,除了进行交换的数之间存在逆序数,原本不动的数和进行交换的数之间也存在逆序对。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<map>
     5 #include<cmath>
     6 using namespace std;
     7 const int maxn = 100010;
     8 const int maxv = maxn * 4;
     9 int a[maxn], b[maxn],val[maxv];
    10 int sumv[maxv];
    11 int tree[maxv];
    12 int maxnum;
    13 map<int, int>mp;
    14 int lowbit(int x)
    15 {
    16     return (x&(-x));
    17 }
    18 int Query(int k)
    19 {
    20     int res = 0;
    21     while (k)
    22     {
    23         res += tree[k];
    24         k -= lowbit(k);
    25     }
    26     return res;
    27 }
    28 void Update(int x, int k)
    29 {
    30     while (x <= maxnum)
    31     {
    32         tree[x] += k;
    33         x += lowbit(x);
    34     }
    35 }
    36 int main()
    37 {
    38     int n;
    39     scanf("%d", &n);
    40     for (int i = 1; i <= n; i++)
    41     {
    42         scanf("%d%d", &a[i], &b[i]);
    43         val[++maxnum] = a[i];
    44         val[++maxnum] = b[i];
    45     }
    46     sort(val + 1, val + 1 + maxnum);
    47     maxnum = unique(val + 1, val + 1 + maxnum) - val-1;
    48     for (int i = 1; i <= maxnum;i++) sumv[i] = sumv[i - 1] + val[i] - val[i - 1] - 1;//统计val[i]前没有被交换的元素个数
    49     for (int i = 1; i <= maxnum; i++) mp[val[i]] = i;//对离散结果编号
    50     //对离散化结果进行交换
    51     for (int i = 1; i <= n; i++)
    52     {
    53         int index1 = mp[a[i]], index2 = mp[b[i]];
    54         swap(val[index1], val[index2]);
    55     }
    56     long long ans = 0;
    57     for (int i = 1; i <= maxnum; i++)
    58     {
    59         int index = mp[val[i]];
    60         Update(index, 1);
    61         ans += Query(maxnum) - Query(index);//找到(index,maxnum]中元素个数,说明在之前已经插入,构成逆序对
    62         ans += abs(sumv[index] - sumv[i]);//如果该数最后仍在原位,值为0;如果后移,则原位与当前之间的数都比该数大;否则,当前的数和原位之间的数都比该数小
    63     }
    64     printf("%lld
    ", ans);
    65     return 0;
    66 }
    View Code
  • 相关阅读:
    MyBatis环境配置
    log4j配置不同的类多个日志文件
    Http协议头、代理
    Apache二级域名实现
    Flash Builder 4.7 完美破解
    网页设计方面,哪些中英文字体的组合能有好的视觉效果
    网页设计中最常用的字体
    sublime text 3 插件:package control
    大量实用工具类、开源包,该帖绝对值得你收藏!
    10个简化Web开发者工作的HTML5开发工具
  • 原文地址:https://www.cnblogs.com/ivan-count/p/8687851.html
Copyright © 2020-2023  润新知