8-6测试总结

时间:2022-12-22 22:15:01

NOIP模拟题day6

题目概览

题目名称

抽牌

插旗

挖宝

程序文件名

draw.pas/c/cpp

flag.pas/c/cpp

treasure.pas/c/cpp

输入文件名

draw.in

flag.in

treasure.in

输出文件名

draw.out

flag.out

path.out

运行时间上限

1

1

1

运行内存上限

512M

512M

512M

比较方式

全文比较

全文比较

全文比较

题目类型

传统

传统

传统

 

 

抽牌(draw)

【题目描述】

一叠牌中有n张牌,其中m张牌是黑牌,剩余的牌是红牌。现在将所有的牌随机打乱,小R从牌堆里依次抽牌,如果小R抽到的牌是黑牌,则他会继续抽牌(他不会将抽到的黑牌放回去);如果他抽到的牌时红牌,则停止抽牌。

现在小R想知道他抽到黑牌的数量的数学期望是多少。

 

【输入格式】

至多10组数据,每组数据一行,包含两个正整数,分别表示n ,m

 

【输出格式】

对于每组数据,输出一行一个实数,保留四位小数,表示抽牌数量的数学期望。

 

【输入样例】

5 3

1 0

 

【输出样例】

1.0000

0.0000

 

【数据范围与约定】

对于20%的数据1<=N<=12;

对于40%的数据1<=N<=2^12;

对于100%的数据1<=N<=2^31-1M<=N

 

插旗(flag)

【题目描述】

n*m的棋盘中,ryz想在某些位置上插上旗,插上一面旗的代价等于当前棋盘中所有旗与这面旗的曼哈顿距离的最大值。插第一面旗不需要代价。求出最小代价和。

 

【输入格式】

第一行两个整数n,m

接下来输出n*m的字符矩阵,如果第i行第j个字符是’.’表示第i行第j列这个点不需要插旗,’Y‘表示要插旗。

 

【输出格式】

输出一行答案

 

【输入样例1

3 3

..Y

Y..

.Y.

 

【输出样例1

5

 

【输入样例2

5 5

.Y..Y

YY..Y

Y.YY.

..YY.

Y.Y.Y

 

【输出样例2

52

 

 

数据范围与约定】

对于20%的数据,n,m<=4

对于40%的数据,n,m<=6

对于60%的数据,n,m<=8

对于80%的数据,n,m<=13

对于100%的数据,n,m<=20

 

 

挖宝(treasure)

【题目描述】

小R在野外发现了一大片宝藏。这批宝藏被藏在m个地道里,每个地道连接两个洞穴。第i个地道连接编号为和的洞穴(),通过该地道需要花费的时间,地道中藏有价值为的宝藏。由于宝藏中蕴含着某些神奇的魔力,小R只能通过地道从编号较小的洞穴走到编号较大的洞穴,即他只能从走到而不能反着走。由于小R的时间非常宝贵,因此他希望能花最小的时间挖到价值最大的宝藏,即他希望平均每个单位时间挖到的宝藏价值尽量大。

现在小R要从1号洞穴出发去n号洞穴,请问在这个过程中,他平均每个单位时间挖到的宝藏价值最大是多少。

 

【输入格式】

第一行两个正整数n,m,分别表示洞穴的数量和地道的数量。

接下来m行,第i行包含四个整数,其中,

 

【输出格式】

一行一个实数,表示平均每个单位时间挖到的宝藏价值的最大值,保留四位小数。

 

【输入样例】

4 4

1 2 3 9

1 3 30 85

2 4 3 6

3 4 3 3

 

【输出样例】

2.6667

 

【数据范围与约定】

对于20%的数据

对于40%的数据 

对于100%的数据

 T1:暴力推,40分,后来根据打表找规律可知ans=m/(n-m+1)

T2:错误的贪心,40分,后坐标转移后DP

T3:二分答案+DP(线扫?)

T2 code

 

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;
#define inf 100000000

int n,m;
int dp[50][50][50][50];
bool map[50][50];

class EllysChessboard
{
    
    int count(int x1,int x2,int y1,int y2)
    {
        if (x1==x2 && y1==y2)    return 0;
        if (x1>x2 || y1>y2)    return inf;
        if (dp[x1][x2][y1][y2]>=0)    return    dp[x1][x2][y1][y2];
        int &ans=dp[x1][x2][y1][y2];
        ans=inf;
        int cost;
        
        cost=count(x1+1,x2,y1,y2);
        for (int i=y1;i<=y2;i++)    if (map[x1][i])
            cost+=max(x2-x1,max(y2-i,i-y1));
        
        ans=min(ans,cost);
        
        cost=count(x1,x2-1,y1,y2);
        for (int i=y1;i<=y2;i++)    if (map[x2][i])
            cost+=max(x2-x1,max(y2-i,i-y1));
        
        ans=min(ans,cost);
        
        cost=count(x1,x2,y1+1,y2);
        for (int i=x1;i<=x2;i++)    if (map[i][y1])
            cost+=max(y2-y1,max(x2-i,i-x1));
        
        ans=min(ans,cost);
        
        cost=count(x1,x2,y1,y2-1);
        for (int i=x1;i<=x2;i++)    if (map[i][y2])
            cost+=max(y2-y1,max(x2-i,i-x1));
        
        ans=min(ans,cost);
        
        return ans;
    }
public:
    int minCost(vector<string> board)
    {
        memset(map,0,sizeof map);
        memset(dp,-1,sizeof dp);
        n=board.size();
        m=board[0].size();
        for (int i=0;i<n;i++)
            for (int j=0;j<m;j++)
            if (board[i][j]!='.')    map[i+j][i-j+m-1]=1;
        return count(0,n+m-2,0,n+m-2);
    }
};

EllysChessboard test;

int main()
{
    freopen("flag.in","r",stdin);
    freopen("flag.out","w",stdout);
    cin>>n>>m;
    string temp;
    vector<string> s;
    for (int i=0;i<n;i++)
    {
        cin>>temp;
        s.push_back(temp);
    }
    cout<<test.minCost(s)<<endl;
    return 0;
}