zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 184 ABCDE 题解

    A - Determinant

    签到。

    B - Quizzes

    签到。

    C - Super Ryuma

    贪心,同时分情况讨论:
    1.本身就在范围里面,就1次(特判起始点和终点重合)。
    2.在两步范围内((|a-c|+|b-d|<=6)),2次。
    3.利用斜线,如果当前不能直接斜线过去,但是通过移动到范围里的点再过去,就2次。
    4.在终点做一条和我两条对角线平行的线,交任意一条对角线上于一点,我就可以先移动到这个点再滑过去,2次。此时要看对角线(坐标和)奇偶性。交不到点就要3次。
    详见代码。

    view code
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<map>
    #include <queue>
    #include<sstream>
    #include <stack>
    #include <set>
    #include <bitset>
    #include<vector>
    #define FAST ios::sync_with_stdio(false)
    #define abs(a) ((a)>=0?(a):-(a))
    #define sz(x) ((int)(x).size())
    #define all(x) (x).begin(),(x).end()
    #define mem(a,b) memset(a,b,sizeof(a))
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define rep(i,a,n) for(int i=a;i<=n;++i)
    #define per(i,n,a) for(int i=n;i>=a;--i)
    #define endl '
    '
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> PII;
    const int maxn = 1e5+200;
    const int inf=0x3f3f3f3f;
    const double eps = 1e-7;
    const double pi=acos(-1.0);
    const int mod = 1e9+7;
    inline int lowbit(int x){return x&(-x);}
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
    inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
    inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
    inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
    inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
    int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
    
    int main()
    {
        ll a = read(), b = read(), c = read(), d = read();
        if(a==c&&b==d)
        {
            cout<<0<<endl;
        }
        else if(a+b==c+d||a-b==c-d||abs(a-c)+abs(b-d)<=3)
        {
            cout<<1<<endl;
        }
        else
        {
            if(abs(a-c)+abs(b-d)<=6) cout<<2<<endl; // 两步方框距离
            else
            {
                int flag = 0;
                for(int i=a-3; i<= a+3; i++) for(int j=b-3; j<=b+3; j++)        //找方框里面能否有直接斜线到终点的
                {
                    if(abs(i-a)+abs(j-b) <= 3&&i+j==c+d||i-j==c-d) flag = 1;
                }
                if(flag) cout<<2<<endl;     //有就万幸
                else    //无的话
                {
    
                    if(((a+b)&1LL)==((c+d)&1LL)) cout<<2<<endl; //看对角线奇偶性
                    else cout<<3<<endl;
                }
            }
        }
    
        return 0;
    }
    
    

    D - increment of coins

    题意:一开始有三种颜色的石子分别为A,B,C个。一次可以随机拿出一个石子,放回两个同颜色的。问把全部都替换成100个同色的需要的步数的期望。

    思路:当前一个状态,如(97,98,99),往下有三个子状态:
    1.(98,98,99)
    2.(97,99,99)
    3.(97,98,100)
    同理这三个子状态往下也有三个状态,直到有一位到100。那么根据期望的定义,我们就知道当前的期望是三种可能需要的步数乘上对应概率,然后加和。
    而这三种可能(子状态)所需要的步数又是他们各自的期望,这就分解了子问题,用DP求解即可。这里采用记忆化搜索。

    view code
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<map>
    #include <queue>
    #include<sstream>
    #include <stack>
    #include <set>
    #include <bitset>
    #include<vector>
    #define FAST ios::sync_with_stdio(false)
    #define abs(a) ((a)>=0?(a):-(a))
    #define sz(x) ((int)(x).size())
    #define all(x) (x).begin(),(x).end()
    #define mem(a,b) memset(a,b,sizeof(a))
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define rep(i,a,n) for(int i=a;i<=n;++i)
    #define per(i,n,a) for(int i=n;i>=a;--i)
    #define endl '
    '
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> PII;
    const int maxn = 1e5+200;
    const int inf=0x3f3f3f3f;
    const double eps = 1e-7;
    const double pi=acos(-1.0);
    const int mod = 1e9+7;
    inline int lowbit(int x){return x&(-x);}
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
    inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
    inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
    inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
    inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
    int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
    
    double dp[105][105][105];
    
    double DP(int A, int B , int C)
    {
        if(A>=100||B>=100||C>=100) return 0;
        if(dp[A][B][C] != -1) return dp[A][B][C];
    
        dp[A][B][C] = ((DP(A+1,B,C)+1)*A/(double)(A+B+C))+((DP(A,B+1,C)+1)*B/(double)(A+B+C))+((DP(A,B,C+1)+1)*C/(double)(A+B+C));
        return dp[A][B][C];
    }
    
    
    int main()
    {
        rep(i,0,101) rep(j,0,101) rep(k,0,101) dp[i][j][k] = -1 ;
        double a, b, c;
        cin>>a>>b>>c;
        printf("%.6lf
    ",DP(a,b,c));
        return 0;
    }
    
    

    E - Third Avenue

    经典BFS问题,在走迷宫的问题上加了传送而已。我们先用map记录每个字母有哪些传送口,然后第一次遇到这个字母的时候,不但可以四方向走,而且还可以将传送位置丢进队列。有一点要注意的是,我第一次遇到这个字母的时候把能走的相同字母都传送过去,下次再遇到这个字母就没必要再看传送了,因为肯定不是最优(走老路),这样就将时间复杂度也降下来了O(26nm)。具体实现见代码。

    view code
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdio>
    #include <string.h>
    #include <stdio.h>
    #include <unordered_map>
    #include<cstring>
    #include<cmath>
    #include<map>
    #include <queue>
    #include<sstream>
    #include <stack>
    #include <set>
    #include <bitset>
    #include<vector>
    #define FAST ios::sync_with_stdio(false)
    #define abs(a) ((a)>=0?(a):-(a))
    #define sz(x) ((int)(x).size())
    #define all(x) (x).begin(),(x).end()
    #define mem(a,b) memset(a,b,sizeof(a))
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define rep(i,a,n) for(int i=a;i<=n;++i)
    #define per(i,n,a) for(int i=n;i>=a;--i)
    #define endl '
    '
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> PII;
    const int maxn = 1e5+200;
    const int inf=0x3f3f3f3f;
    const double eps = 1e-7;
    const double pi=acos(-1.0);
    const int mod = 1e9+7;
    inline int lowbit(int x){return x&(-x);}
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
    inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
    inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
    inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
    inline int read(){ int f = 1; int x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
    int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
    
    char s[3000][3000];
    int n, m;
    int vis[3000][3000];
    int d[3000][3000];
    int path[30];
    unordered_map<int, vector<PII> > to;
    
    int Sx,Sy,  Gx,Gy;
    
    bool check(int x, int y)
    {
        if(x>n||x<1||y>m||y<1||vis[x][y]||s[x][y]=='#') return false;
        return true;
    }
    
    ll bfs()
    {
        queue<PII> q;
        d[Sx][Sy] = 0;
        vis[Sx][Sy] = 1;
        q.push(mp(Sx,Sy));
        while(!q.empty())
        {
            int x = q.front().fi;
            int y = q.front().se;
            q.pop();
            if(s[x][y] == 'G') return d[x][y];
            rep(i,0,3)
            {
                int xx = x + dir[i][0];
                int yy = y + dir[i][1];
                if(check(xx,yy)&&!vis[xx][yy])
                {
                    vis[xx][yy] = 1;
                    d[xx][yy] = d[x][y] + 1;
                    q.push(mp(xx,yy));
                }
            }
    
            if(s[x][y]>='a'&&s[x][y]<='z'&&!path[s[x][y]-'a'])
            {
                path[s[x][y]-'a'] = 1;
                for(int i=0; i<to[s[x][y]-'a'].size(); i++)
                {
                    int tox = to[s[x][y]-'a'][i].fi;
                    int toy = to[s[x][y]-'a'][i].se;
    
                    if(check(tox,toy)&&!vis[tox][toy]&&!(tox==x&&toy==y))
                    {
                        vis[tox][toy] = 1;
                        d[tox][toy] = d[x][y] + 1;
                        q.push(mp(tox,toy));
                    }
                }
            }
        }
        return -1;
    }
    
    int main()
    {
        cin>>n>>m;
        char ch = getchar();
        rep(i,1,n) scanf("%s",s[i]+1);
    
        rep(i,1,n) rep(j,1,m)
        {
            if(s[i][j] == 'S') Sx = i, Sy = j;
            else if(s[i][j]=='G') Gx = i, Gy = j;
            else if(s[i][j]>='a'&&s[i][j]<='z')
            to[s[i][j]-'a'].pb(mp(i,j));
        }
        ll ans = bfs();
        cout<<ans<<endl;
        return 0;
    }
    
    

  • 相关阅读:
    安装VMware Workstation提示the msi failed的解决办法
    windows2008中没有右键个性化
    delphi调用AdoQuery实现SqlSever的存储过程(返回)
    delphi 如何解决假死
    用A4打印总账,预览及打印无表头。。
    解决VMWare“Could not get vmci driver version句柄无效”的错误
    第一章 认识jQuery
    jQuery $.each用法
    jquery ui tabs详解(中文)
    javascript面向对象
  • 原文地址:https://www.cnblogs.com/Bgwithcode/p/14023868.html
Copyright © 2011-2022 走看看