• Codeforces Round #301 (Div. 2) 题解


    题目链接:http://codeforces.com/contest/540

    A、题意:你现在要解开一个密码锁,给你当前密码锁的状态和目标状态,你要拨动最少次数到达目标状态

    解:贪心

     1 /*
     2  * Problem:  
     3  * Author:  SHJWUDP
     4  * Created Time:  2015/6/4 星期四 15:06:51
     5  * File Name: 233.cpp
     6  * State: 
     7  * Memo: 
     8  */
     9 #include <iostream>
    10 #include <cstdio>
    11 #include <cstring>
    12 #include <algorithm>
    13 
    14 using namespace std;
    15 
    16 const int MaxA=1e3+7;
    17 
    18 char strA[MaxA];
    19 char strB[MaxA];
    20 int main() {
    21 #ifndef ONLINE_JUDGE
    22     freopen("in", "r", stdin);
    23     //freopen("out", "w", stdout);
    24 #endif
    25     int n;
    26     while(~scanf("%d", &n)) {
    27         scanf("%s%s", strA, strB);
    28         int ans=0;
    29         for(int i=0; i<n; i++) {
    30             ans+=min(abs(strA[i]-strB[i]), min(strA[i], strB[i])+10-max(strA[i], strB[i]));
    31         }
    32         printf("%d
    ", ans);
    33     }
    34     return 0;
    35 }
    View Code

    B、题意:现在有n门课要考试(n是奇数),每门的总分都是p且最少都要考1分,现在已经考了k门(k门成绩给出了),问你要总分小于x且,各门考分的中位数大于y该怎么考,如果有多解,输出任意一个即可

    解:贪心,一种构造方法:比y大的数如果小于n/2个,那么中位数一定取y,然后比中位数大的数有空缺就拿y补充,比中位数小的数拿1补充

     1 /*
     2  * Problem:  
     3  * Author:  SHJWUDP
     4  * Created Time:  2015/6/4 星期四 15:06:51
     5  * File Name: 233.cpp
     6  * State: 
     7  * Memo: 
     8  */
     9 #include <iostream>
    10 #include <cstdio>
    11 #include <cstring>
    12 #include <algorithm>
    13 
    14 using namespace std;
    15 
    16 typedef long long int64;
    17 
    18 const int MaxA=1e3+7;
    19 
    20 int64 n, k, p, x, y;
    21 int64 arr[MaxA];
    22 int main() {
    23 #ifndef ONLINE_JUDGE
    24     freopen("in", "r", stdin);
    25     //freopen("out", "w", stdout);
    26 #endif
    27     while(~scanf("%I64d%I64d%I64d%I64d%I64d", &n, &k, &p, &x, &y)) {
    28         int64 sum=0;
    29         int cnt=0;
    30         for(int i=0; i<k; i++) {
    31             scanf("%I64d", &arr[i]);
    32             sum+=arr[i];
    33             if(arr[i]>=y) cnt++;
    34         }
    35         if(sum+n-k>x) {
    36             puts("-1"); continue;
    37         }
    38 
    39         int need=(n>>1)+1;
    40         if(cnt>=need) {
    41             for(int i=k; i<n; i++) {
    42                 printf("%d%c", 1, " 
    "[i==n-1]);
    43             }
    44         } else {
    45             int tmp=need-cnt;
    46             if(tmp>n-k || sum+tmp*y+(n-k-tmp)>x) {
    47                 puts("-1");
    48             } else {
    49                 int num=tmp;
    50                 for(int i=k; i<n; i++) {
    51                     if(num) {
    52                         printf("%I64d%c", y, " 
    "[i==n-1]);
    53                         num--;
    54                     } else printf("%d%c", 1, " 
    "[i==n-1]);
    55                 }
    56             }
    57         }
    58     }
    59     return 0;
    60 }
    View Code

    C、题意:冰洞游戏,你在一张n*m的地图上(你占一个格子的空间),地图上的每个格子有两种状态,'X':踩在上面会掉下去,'.':踩在上面会变成'X',给你初始位置和目标位置,问你是否能够在目标位置掉下去

    解:搜索+贪心,看看能不能从到达目标位置,再根据目标位置的状态与度数判断是否可以掉下去,有初始位置和目标位置相邻或重合的时候需要特判一下

     1 /*
     2  * Problem:  
     3  * Author:  SHJWUDP
     4  * Created Time:  2015/6/4 星期四 15:06:51
     5  * File Name: 233.cpp
     6  * State: 
     7  * Memo: 
     8  */
     9 #include <iostream>
    10 #include <cstdio>
    11 #include <cstring>
    12 #include <algorithm>
    13 #include <queue>
    14 
    15 using namespace std;
    16 
    17 typedef long long int64;
    18 
    19 const int MaxA=500+7;
    20 
    21 int n, m;
    22 char map[MaxA][MaxA];
    23 int dir[][2]={{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
    24 int sx, sy, tx, ty;
    25 bool bfs() {
    26     queue<pair<int, int> > Q;
    27     Q.push(make_pair(sx, sy));
    28     while(!Q.empty()) {
    29         pair<int, int> u=Q.front(); Q.pop();
    30         for(int k=0; k<4; k++) {
    31             int xx=u.first+dir[k][0];
    32             int yy=u.second+dir[k][1];
    33             if(xx<0 || xx>=n || yy<0 || yy>=m) continue;
    34             if(xx==tx && yy==ty) return true;
    35             if(map[xx][yy]=='X') continue;
    36             map[xx][yy]='X';
    37             Q.push(make_pair(xx, yy));
    38         }
    39     }
    40     return false;
    41 }
    42 int main() {
    43 #ifndef ONLINE_JUDGE
    44     freopen("in", "r", stdin);
    45     //freopen("out", "w", stdout);
    46 #endif
    47     while(~scanf("%d%d", &n, &m)) {
    48         for(int i=0; i<n; i++) {
    49             scanf("%s", map[i]);
    50         }
    51         scanf("%d%d%d%d", &sx, &sy, &tx, &ty);
    52         sx--; sy--; tx--; ty--;
    53         int dg=0;
    54         for(int k=0; k<4; k++) {
    55             int xx=tx+dir[k][0];
    56             int yy=ty+dir[k][1];
    57             if(xx<0 || xx>=n || yy<0 || yy>=m) continue;
    58             if(map[xx][yy]!='X' || (xx==sx && yy==sy)) dg++;
    59         }
    60         if(sx==tx && sy==ty) {
    61             puts(dg>=1?"YES":"NO");
    62             continue;
    63         }
    64     //  cout<<"dg: "<<dg<<endl;
    65     //  cout<<"flag; "<<bfs()<<endl;
    66         if(((dg>=2 && map[tx][ty]=='.') || map[tx][ty]=='X')
    67                 && bfs()) {
    68             puts("YES");
    69         } else puts("NO");
    70     }
    71     return 0;
    72 }
    View Code

    D、题意:在一个岛上住着石头、剪刀、布三种生物,告诉你每种生物的数量r,s,p问你在无限长的时间后最后存活的生物是石头,剪刀还是布的概率分别是多少

    解:三维dp,注意转移的话有概率会维持原状态,那么对于转移概率实际上是目标状态概率/生物消减概率

     1 /*
     2  * Problem:  
     3  * Author:  SHJWUDP
     4  * Created Time:  2015/6/4 星期四 15:06:51
     5  * File Name: 233.cpp
     6  * State: 
     7  * Memo: 
     8  */
     9 #include <iostream>
    10 #include <cstdio>
    11 #include <cstring>
    12 #include <algorithm>
    13 #include <queue>
    14 
    15 using namespace std;
    16 
    17 typedef long long int64;
    18 
    19 const double eps=1e-10;
    20 
    21 const int MaxA=100+7;
    22 
    23 int r, s, p;
    24 double f[MaxA][MaxA][MaxA];
    25 int main() {
    26 #ifndef ONLINE_JUDGE
    27     freopen("in", "r", stdin);
    28     //freopen("out", "w", stdout);
    29 #endif
    30     while(~scanf("%d%d%d", &r, &s, &p)) {
    31         memset(f, 0, sizeof(f));
    32         f[r][s][p]=1;
    33         for(int i=r; i>=0; i--) {
    34             for(int j=s; j>=0; j--) {
    35                 for(int k=p; k>=0; k--) {
    36                     double p1=i*k, p2=i*j, p3=j*k;
    37                     if(k && i) f[i-1][j][k]+=f[i][j][k]*p1/(p1+p2+p3);
    38                     if(i && j) f[i][j-1][k]+=f[i][j][k]*p2/(p1+p2+p3);
    39                     if(j && k) f[i][j][k-1]+=f[i][j][k]*p3/(p1+p2+p3);
    40                 }
    41             }
    42         }
    43         double ansA=0, ansB=0, ansC=0;
    44         for(int i=1; i<=r; i++) ansA+=f[i][0][0];
    45         for(int i=1; i<=s; i++) ansB+=f[0][i][0];
    46         for(int i=1; i<=p; i++) ansC+=f[0][0][i];
    47         double sum=ansA+ansB+ansC;
    48         printf("%.12f %.12f %.12f
    ", ansA/sum, ansB/sum, ansC/sum);
    49     }
    50     return 0;
    51 }
    View Code

    E、题意:给你一个无限长的序列{1,2,3,...},问你在执行交换操作n次后的逆序数

    解:树状数组求逆序数,经典题变体,需要考虑参与交换的元素与交换元素之间的元素

     1 /*
     2  * Problem:  
     3  * Author:  SHJWUDP
     4  * Created Time:  2015/6/8 星期一 16:51:21
     5  * File Name: 233.cpp
     6  * State: 
     7  * Memo: 
     8  */
     9 #include <iostream>
    10 #include <cstdio>
    11 #include <cstring>
    12 #include <algorithm>
    13 
    14 using namespace std;
    15 
    16 typedef long long int64;
    17 
    18 const int MaxA=1e5+7;
    19 const int MaxB=MaxA<<1;
    20 
    21 struct Fenwick {
    22     int n;
    23     int c[MaxB];
    24 
    25     void init(int _n) {
    26         this->n=_n;
    27         memset(c, 0, sizeof(c[0])*(n+3));
    28     }
    29 
    30     int lowbit(int x) {
    31         return x&-x;
    32     }
    33 
    34     void update(int x, int v) {
    35         while(x<=n) {
    36             c[x]+=v;
    37             x+=lowbit(x);
    38         }
    39     }
    40 
    41     int query(int x) {
    42         int res=0;
    43         while(x>0) {
    44             res+=c[x];
    45             x-=lowbit(x);
    46         }
    47         return res;
    48     }
    49 } fw;
    50 
    51 int n;
    52 pair<int, int> op[MaxA];
    53 int table[MaxB], tn;
    54 int arr[MaxB], an;
    55 int find(int x) {
    56     return lower_bound(table, table+tn, x)-table;
    57 }
    58 int main() {
    59 #ifndef ONLINE_JUDGE
    60     freopen("in", "r", stdin);
    61     //freopen("out", "w", stdout);
    62 #endif
    63     while(~scanf("%d", &n)) {
    64         tn=0;
    65         for(int i=0; i<n; i++) {
    66             scanf("%d%d", &op[i].first, &op[i].second);
    67             table[tn++]=op[i].first;
    68             table[tn++]=op[i].second;
    69         }
    70         sort(table, table+tn);
    71         tn=unique(table, table+tn)-table;
    72         memcpy(arr, table, tn*sizeof(table[0]));
    73         an=tn;
    74 
    75         for(int i=0; i<n; i++) {
    76             swap(arr[find(op[i].first)], arr[find(op[i].second)]);
    77         }
    78         fw.init(tn);
    79         int64 ans=0;
    80         for(int i=0; i<an; i++) {
    81             int p=find(arr[i])+1;
    82         //  cout<<"tn: "<<tn<<"	pos: "<<p<<endl;
    83             ans+=fw.query(tn)-fw.query(p);
    84         //  cout<<fw.query(tn)<<"	"<<fw.query(p)<<endl;
    85             if(i!=an-1) {
    86                 int q=find(table[i])+1;
    87                 fw.update(p, 1);
    88                 int num=table[i+1]-table[i]-1;
    89                 ans+=(int64)num*(fw.query(tn)-fw.query(q));
    90             //  cout<<fw.query(tn)<<"	"<<fw.query(q)<<endl;
    91                 fw.update(q+1, num);
    92             }
    93         }
    94         printf("%I64d
    ", ans);
    95     }
    96     return 0;
    97 }
    View Code
  • 相关阅读:
    限制结果集行数
    函数的差异
    运算符的差异
    数据类型的差异
    简介
    Spring源码阅读入门指引
    Spring的三种注入方式
    AOP面向切面编程
    leetcode771
    leetcode669
  • 原文地址:https://www.cnblogs.com/shjwudp/p/4561889.html
Copyright © 2020-2023  润新知