【高中组集体赛前热身赛】题解

(第一次给学弟们学妹写题解,可能有些地方我认为简单的可能没有仔细解释,所以导致没有讲清楚的一定要勤奋问百度,或者底下留言)

【A-投掷硬币】

题解:基础DP(动态规划),dp[i][j]表示从第一个硬币开始翻,翻到第i个硬币的时候,翻到正面的有j个。那么dp[i][j]由dp[i-1][j-1](第i个是正面)和dp[i-1][j](第i个是反面)转移而来。所以由方程:dp[i][j]=dp[i-1][j]*(1.0-p[i])+dp[i-1][j-1]*p[i];当然j=0的话只能优dp[i-1][0]转移而来。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=1010;
double dp[maxn][maxn],p[maxn];
int main()
{
    int N,M,i,j;
    scanf("%d%d",&N,&M);
    dp[0][0]=1.0;
    for(i=1;i<=N;i++) scanf("%lf",&p[i]);
    for(i=1;i<=N;i++){
        dp[i][0]=dp[i-1][0]*(1.0-p[i]);
        for(j=1;j<=M;j++){
           dp[i][j]=dp[i-1][j]*(1.0-p[i])+dp[i-1][j-1]*p[i];
        }
    }
    printf("%.4lf\n",dp[N][M]);
    return 0;
}

【B-最大集合】

题解:每一个集合是封闭的。即每个元素只会出现在一个集合里面,而且从每个集合的任意元素出发,都可以走到下一个元素,直到走到起始元素。

所以DFS搜索就可以了,把每次搜索到的标记一下。对于没有搜索到的,作为起点,继续搜索。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=100010;
int vis[maxn],a[maxn],cnt;
int main()
{
    int N,i,ans=0,tmp;
    scanf("%d",&N);
    for(i=1;i<=N;i++) scanf("%d",&a[i]);
    for(i=1;i<=N;i++){
        if(vis[i]==0){
            cnt=1; tmp=i;
            vis[tmp]=1;
            while(!vis[a[tmp]]){
                cnt++;
                tmp=a[tmp];
            }
            ans=max(ans,cnt);
        }
    }
    printf("%d\n",ans);
    return 0;
} 

【C-第K小分数】

枚举每一个数为分母,然后二分分子。 二分的复杂度是O(logn),然后枚举N个数作为分母,这样的话复杂度就是O(N*logN)。不会二分的仔细看代码就会了。

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
const int maxn=1010;
ll a[maxn],N;
ll check(int x,int y)
{
    ll res=0;
    for(int i=1;i<=N;i++){
        res+=(a[i]*x/y);
    } return res;
}
int main()
{
    ll K,L,R,Mid,tmp;
    scanf("%lld%lld",&N,&K);
    for(int i=1;i<=N;i++) scanf("%d",&a[i]);
    for(int i=1;i<=N;i++){
        L=1; R=a[i]-1;
        while(L<=R){
            Mid=(L+R)/2;
            tmp=check(Mid,a[i]);
            if(tmp==K){
                printf("%lld/%lld\n",Mid,a[i]);
                return 0;
            }
            else if(tmp<K) L=Mid+1;
            else R=Mid-1;
        }
    }return 0;
}

【D-最大子矩阵】

由于A>=1满足区间和的单调性。所以可以用双指针,即枚举矩形的上下边界,然后移动左右边界

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=300;
int N,M,K,a[maxn][maxn],sum[maxn][maxn];
int vis[10010],num,Now,ans=-1;
int main()
{
    int i,j,k,L,R;
    scanf("%d%d%d",&N,&M,&K);
    for(i=1;i<=N;i++)
      for(j=1;j<=M;j++){
        scanf("%d",&a[i][j]);
        sum[i][j]=sum[i-1][j]+a[i][j];
    }

    for(i=1;i<=N;i++)
      for(j=i;j<=N;j++){
         memset(vis,0,sizeof(vis));
         num=0; Now=0;
         for(R=1,L=1;R<=M;R++){
             num+=j-i+1; Now+=sum[j][R]-sum[i-1][R];
             while(Now>K&&L<=R) {
                num-=j-i+1;
                Now-=sum[j][L]-sum[i-1][L];
                L++;
             }
             if(Now<=K&&L<=R) ans=max(ans,num);
         }
    }
    printf("%d\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/hua-dong/p/8457386.html

时间: 2024-10-19 22:50:33

【高中组集体赛前热身赛】题解的相关文章

第七届省赛赛前交流赛部分题解

A题: Yougth's Game[Ⅲ]( 区间dp ) 这是在省赛前热身赛出的题目,可能是题目中有用到博弈的思想,很多人都在做,而且在尝试暴力.但是没有人往dp的方向上想. 题目类型:动态规划+博弈 分析:题意描述的很清楚,就是选择在两端取数,当前取的数不仅能够影响下一次的结果,而且能够影响后面的结果...又是一个求最优值,那么是不是可以往dp的方向上想了.区间dp 定义状态dp[ i ] [ j ] 为从 i 到 j 上A的得分,那么B的得分就是sum(i,j)-dp[ i ] [ j ]

KTU Programming Camp (Winter Training Day 1)

A.B.C(By musashiheart) 0216个人赛前三道题解 E(By ggg) Gym - 100735E Restore

CF786B Legacy(线段树优化建图+最短路)

在qbxt某营集体做的 题解里以及外地OIer基本上都写两颗线段树的 而我们六安的OIer神TM思维一致--只用一颗线段树,类似于一维分层图的思想,第二层上与第一层相对应的结点的编号是第一层结点编号+NUM,而且貌似比分颗的思维正常一点,因为满足lson=k<<1,rson=k<<1|1,和一般的线段树相似度高. 至于为什么要分颗或分层,容易想明白树边(辅助边)必须是双向的(因为要用祖先结点的出入信息),但如果不分颗或分层的话求出来最短路不很明显是0了吗QwQ 所以分层的话父向子应

BUCT蓝桥杯热身赛II题解

A题 编码(decode) 签到题,没有可说的. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <set> 5 6 using namespace std; 7 8 int main () { 9 int mark[26]; 10 memset(mark,0,sizeof(mark)); 11 string child,goal;int N; 12 cin

BUCT蓝桥杯热身赛I题解

A 题 十六进制转换(hex) 看起来是一个水题,可是事实上确实是个水题.如果你按照题目的意思来,先把16进制转化成10进制,再把10进制转换成8进制,不好写. 所以从2进制的思想看16进制的数每一个数都是由4位二进制组成,然而8进制数是有3位二进制组成,所以我们大可把16进制先转成2进制,在从 二进制转成8进制,注意前导0. 注意姿势,由于姿势的问题,超时了3次,真冤.代码见下方 1 #include <iostream> 2 #include <cstdio> 3 #inclu

第八届蓝桥杯省赛题解

一直以来,自己的科技类竞赛实在太少了,确实是自己的问题,从大学没有对自己有一个明确的规划,现在再回过头去恶补很多的知识点.悔当初,甚至怀疑自己,却已经来不及,最近因为某些人某些事让自己心情变得十分差,把自己弄得狼狈不堪. 今年是第一次参加蓝桥杯比赛,原本寒假就打算好好复习的,一直没有静下心来准备,正式做题是在比赛前3天.校区是在绵阳师范墨家小区,还以为头一天就要赶过去,后面接到学院老师的电话说一起跟着大部队过去,于是就在早上6点起来,看了会算法,吃早餐后就随着校车去了. 这次去参赛的都是比较厉害

8.7联考题解

前两题很水啊--没必要开三篇了就扔到一篇里去了.改水题异常艰难,代码量很小然而我又被什么奇怪的东西绊住了. Passward 时间限制: 1 Sec  内存限制: 512 MB 题目描述 你来到了一个庙前,庙牌上有一个仅包含小写字母的字符串 s. 传说打开庙门的密码是这个字符串的一个子串 t,并且 t 既是 s 的前缀又是 s 的后缀并且还在 s 的中间位置出现过一次. 如果存在这样的串,请你输出这个串,如有多个满足条件的串,输出最长的那一个. 如果不存在这样的串,输出"Just a legen

上海邀请赛之热身赛2_2013成都邀请赛

先写总结. 感觉这次跟scf和sjc组队有种瞬间碉堡了的感觉,虽然是临时组建的队伍凑齐准备去上海参加邀请赛,从这次比赛磨练配合. 今天比赛难度比前天那次的难度低,感觉更适合我们来练习. 话说好像比赛提早了5分钟,我们三个人都不知道,五分钟后一看A题学长已经A了,一想肯定特水...我就没看题,sjc和scf两个看了题,scf就开始敲了,我刚开始负责翻译题,虽然我英语是个渣渣...没办法,没翻译他们几乎做不出题...我就没做题,翻译了B和G.scf敲了貌似好久才完成(赛后重做,特水,基本3分钟就可以

splay专题复习——bzoj 3224 &amp; 1862 &amp; 1503 题解

[前言]快要省选二试了.上次去被虐出翔了~~这次即便是打酱油,也要打出风采!于是暂停新东西的学习,然后开始复习以前的知识,为骗分做准备.PS:区间翻转的暂时跳过,就算学了也来不及巩固了. [BZOJ3224] 3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1477  Solved: 570 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 1. 插入