牛客比赛 2019年3月22日提高组(自闭场)(补题)

问题一

Input:

5 5
0 0 5 0 0
0 4 3 8 2
9 5 7 2 7
1 9 6 5 4
1 0 0 6 2

Output:

4

Input:

10 10
0 0 0 0 0 0 0 0 0 0
0 5 2 6 4 3 1 7 8 0
0 6 4 2 3 5 1 4 6 0
0 3 6 4 1 2 4 7 8 0
0 2 5 5 1 2 3 4 4 0
0 2 3 1 5 4 4 1 4 0
0 4 1 2 3 4 5 2 1 0
0 7 5 5 1 5 4 5 7 0
0 1 3 5 5 4 6 8 7 0
0 0 0 0 0 0 0 0 0 0

Output:

23

Hint:
- 对于10%的数据, n, m ≤ 4, h ≤ 5;
- 对于前50%的数据, n, m ≤ 20, h ≤ 10;
- 对于前70%的数据, n, m ≤ 100, h ≤ 50;
- 对于另外10%的数据, 不存在两个连续的块能积水;
- 对于95%的数据, n, m ≤ 500, h ≤ 100.
- 对于100%的数据, n, m ≤ 1000, h ≤ 1000,000,000.

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #include<cstring>
 5 using namespace std;
 6 
 7 const int N = 1e3+3;
 8 
 9 int xy[4][2]={-1, 0, 0, -1, 0, 1, 1, 0};
10 
11 struct pnt{
12     int x,y,h;
13     bool operator<(const pnt a)const{
14         return h>a.h;
15     }
16 };
17 
18 priority_queue<pnt>q;
19 
20 int h[N][N],f[N][N];
21 
22 int main()
23 {
24     int n,m,i,j;
25     cin >> n >> m;
26     memset(f,-1,sizeof(f));
27     for (i = 1; i <= n; i++)
28         for (j = 1; j <= m; j++){
29             cin >> h[i][j];
30             if (i == 1 || j == 1 || i == n || j == m)
31                 q.push((pnt){i, j, h[i][j]}), f[i][j] = 0;
32         }
33     while (!q.empty()){
34         pnt v = q.top();
35         q.pop();
36         for (i = 0; i < 4; i++) {
37             int dx = v.x+xy[i][0], dy = v.y + xy[i][1];
38             if (dx > 0 && dx <= n && dy > 0 && dy <= m && f[dx][dy] == -1){
39                 q.push((pnt){dx, dy, h[dx][dy]});
40                 f[dx][dy] = max(f[v.x][v.y], v.h);
41             }
42         }
43     }
44     long long ans = 0;
45     for (i = 1; i <= n; i++)
46         for (j = 1;j <= m; j++)
47             ans += max(f[i][j]-h[i][j], 0);
48     cout << ans << endl;
49 }

问题二:

Input:

4 2
1 2
2 3
2 4

 

Output:

2

 

Hint:


2号点到1, 3, 4点的路径的厌恶度都是2,厌恶度总和为 6
1, 3, 4到其它点的路径厌恶度之和均为2 + 6 + 6 = 14


数据范围
- 对于前10%的数据, n ≤ 10;
- 对于另外20%的数据, n ≤ 500 且 保证图为一条链;
- 对于另外20%的数据, n ≤ 500, k = 2;
- 对于另外20%的数据, k = 1;
- 对于100%的数据,n ≤ 20000, k ≤ 10,除 对于20%的数据保证图为一条链外 图保证随机!!!

 

#include<bits/stdc++.h>
using namespace std;
 
#define Uni All Right
#define REP(i,a,b) for(int i=(a),i##_end_=(b);i<i##_end_;++i)
#define DREP(i,a,b) for(int i=(a),i##_end_=(b);i>i##_end_;--i)
#define LCREP(i,a) for(int &i=Cur[a];i;i=Next[i])
#define LREP(i,a) for(int i=Head[a];i;i=Next[i])
#define LL long long
#define DB double
 
static const int M=22;
int n,m,T,v;
DB Tmp;
struct Node{
    DB V[M][M];
    void Clear(){memset(V,0,sizeof(V));}
    void Init(DB p){
        Clear();
        REP(i,0,m){
            if(i==m-1)p=0;
            V[i][i]=1-p;
            V[i][i+1]=p;
            V[i][m]=i;
        }
        V[m][m]=1;
    }
    Node operator *(const Node &_)const{
        Node P;P.Clear();
        REP(i,0,m+1)REP(j,0,m+1)REP(k,0,m+1)
            P.V[i][j]+=V[i][k]*_.V[k][j];
        return P;
    }
}K,Ans;
 
int main(){
    scanf("%d%d%d%d",&n,&m,&T,&v);
    m-=n,Tmp+=1.0*n*T+(T-1);
    Ans.V[0][0]=1;
    for(int l=1,r;l<T;l=r){
        r=T/(T/(l+1));
        K.Init(T/r*1.0/T);
        int p=r-l;
        for(;p;K=K*K,p>>=1)if(p&1)Ans=Ans*K;
    }
     
    printf("%.9lf
",(Ans.V[0][m]+Tmp)*v);
    return 0;
}

问题三:

Input:

 6 10 1 1

Output:

6

Hint:

第0个时刻它有100%的概率新建一个SCV.
此时6个SCV采了6单位晶体.
第1时刻采集矿物完成,共采集6单位晶体.

 
- 对于30%的数据, 满足 T <= 106;
- 对于另外10%的数据满足 m = n+1;

- 对于另外10%的数据满足 m = n+2;
- 对于100%的数据, 满足 T  <= 109 , 0 <= n, m <= 20;
#include<bits/stdc++.h>
using namespace std;
 
#define Uni All Right
#define REP(i,a,b) for(int i=(a),i##_end_=(b);i<i##_end_;++i)
#define DREP(i,a,b) for(int i=(a),i##_end_=(b);i>i##_end_;--i)
#define LCREP(i,a) for(int &i=Cur[a];i;i=Next[i])
#define LREP(i,a) for(int i=Head[a];i;i=Next[i])
#define LL long long
#define DB double
 
static const int M=22;
int n,m,T,v;
DB Tmp;
struct Node{
    DB V[M][M];
    void Clear(){memset(V,0,sizeof(V));}
    void Init(DB p){
        Clear();
        REP(i,0,m){
            if(i==m-1)p=0;
            V[i][i]=1-p;
            V[i][i+1]=p;
            V[i][m]=i;
        }
        V[m][m]=1;
    }
    Node operator *(const Node &_)const{
        Node P;P.Clear();
        REP(i,0,m+1)REP(j,0,m+1)REP(k,0,m+1)
            P.V[i][j]+=V[i][k]*_.V[k][j];
        return P;
    }
}K,Ans;
 
int main(){
    scanf("%d%d%d%d",&n,&m,&T,&v);
    m-=n,Tmp+=1.0*n*T+(T-1);
    Ans.V[0][0]=1;
    for(int l=1,r;l<T;l=r){
        r=T/(T/(l+1));
        K.Init(T/r*1.0/T);
        int p=r-l;
        for(;p;K=K*K,p>>=1)if(p&1)Ans=Ans*K;
    }
     
    printf("%.9lf
",(Ans.V[0][m]+Tmp)*v);
    return 0;
}
作者:LightAc
出处:https://www.cnblogs.com/lightac/
联系:
Email: dzz@stu.ouc.edu.cn
QQ: 1171613053
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/lightac/p/10580820.html