2019中山纪念中学夏令营-Day2[JZOJ]

博客的开始,先聊聊代码实现:

每次比赛以后,要有归纳错误的习惯.

错误小结:

1.读入:scanf(“%c”)会读入回车和空格,但cin不会.

2.对于二维数组的输入,不能把m,n搞混了,会引起严重的程序错误,轻则Wrong Answer,重则Run Time Error.

注意DFS的边界问题。

比赛内容及赛后反思

Problem 1 

 

题目描述

  近期,农场出现了D (1<= D <=15)种细菌。John 要从他的 N (1<= N <=1,000)头奶牛中尽可能多地选些产奶。但是如果选中的奶牛携带了超过 K (1<= K <=D)种不同细菌,所生产的奶就不合格。请你帮助John 计算出最多可以选择多少头奶牛。
 

输入

第一行:三个整数 N, D, K

下面N行:第行表示一头牛所携带的细菌情况。第一个整数 di 表示这头牛所携带的细菌种类数,后面di个整数表示这些细菌的各自种类标号。

输出

只一个数 M,最大可选奶牛数。
 

样例输入

 

样例输出

 
 

数据范围限制

 
 

提示

样例

 















输入  

6 3 2         

0

1 1

1 2

1 3

2 2 1

2 2 1

选择:

1,2,3,5,6

只有1#和2#两种细菌

输出

5

    

 


 
 
 
 

 

 

 

Fortuna OJ 项目
作者: moreDRD; 协力: twilightMcHobby
由 CodeIgniter / Bootstrap 驱动
Glyphicons 提供图标

 

思路:暴搜。

代码:(TLE错误代码22.2分)

#include <cstdio>
#include <iostream>
#define rr register
using namespace std;
int n,d,k,a[1000][16],ans1=0,ans=0;
bool c[16];
int max(int a,int b)
{
    if(a>b)
    return a;
    return b;
}
void dfs(int i,bool xz,int jun,int sum)
{
    bool tmp[16],temp=jun;
    for(rr int j=1;j<=15;j++)
        tmp[j]=c[j];
    if(jun>k)
    return;
    if(i>n)
    {
        ans=max(ans,sum);
        return;
    }
    if(xz)
    {
        for(rr int j=1;j<=k;j++)
            if(a[i][j] && a[i][j]!=c[j])
            {
                    c[j]=a[i][j];
                    jun++;
                }
        if(jun>k)
        {
            for(rr int j=1;j<=15;j++)
                c[j]=tmp[j];
            jun=temp;
        }
        else
        sum++;
    }
    dfs(i+1,true,jun,sum);
    dfs(i+1,false,jun,sum);
}
int main()
{
    int tmp;
    scanf("%d %d %d",&n,&d,&k);
    for(rr int i=1;i<=n;i++)
    {
        scanf("%d",&a[i][0]);
        if(a[i][0]==0)
        {
            ans1++;
            i--;
            n--;
        }
        if(a[i][0]>k)
        {
            i--;
            n--;
            continue;
            }
        for(rr int j=1;j<=a[i][0];j++)
        {
            scanf("%d",&tmp);
            a[i][tmp]=true;
            }    
    }    
    dfs(1,true,0,0);
    dfs(1,false,0,0);
    printf("%d",ans);
}

正解以后附(本人还未提交测试代码)

Problem 2

题目描述

  John的奶牛们计划要跳到月亮上去。它们请魔法师配制了 P (1 <= P <=150,000)种药水,这些药水必需安原来的先后次序使用,但中间可以跳过一些药水不吃。每种药水有一个“强度”值 s ( 1 <= s <= 500 ),表示可以增强牛的跳跃能力。然而,药力的作用却是交替相反方向起作用,也就是说:当第奇数次吃药时,牛获得跳的更高的能力,而第偶数吃药时,却降低了跳高能力。在吃药前,牛的跳高能力当然为 0 。

   每种药只能吃一次,开始时为第1次吃药。

   请求出牛可能跳到的最高高度--最大跳跃能力。

 
 

输入

第一行:一个整数 P

下面P行:每行一个整数,表示按先后次序要吃的药水的“强度”。

输出

只一个整数,表示最大弹跳能力。
 

样例输入

 

样例输出

 
 

数据范围限制

 
 

提示

 















输入

8          

7

2

1

8

4

3

5

6

去掉第2、4两种药水,

吃药为:

7,1,8,3,6;

最终能力为:

7-1+8-3+6=17

输出

17

    

 

 
 
 
 
Fortuna OJ 项目
作者: moreDRD; 协力: twilightMcHobby
由 CodeIgniter / Bootstrap 驱动
Glyphicons 提供图标

思路:动态规划。

附上代码:

(TLE错误代码20分DFS)

#include <cstdio>
#include <iostream>
#define rr register
using namespace std;
int p,a[150002],ans;
int max(int a,int b)
{
    if(a>b)
    return a;
    return b;
}
void dfs(rr int i,bool xz,bool zf,int sum)
{
    if(i>p)
    {
        ans=max(ans,sum);
        return;
    }
    if(xz)
    {
        if(zf)
        sum+=a[i];
        else
        sum-=a[i];
        zf=!zf;
    }
    dfs(i+1,true,zf,sum);
    dfs(i+1,false,zf,sum);
}
int main()
{
    scanf("%d",&p);
    for(rr int i=1;i<=p;i++)
        scanf("%d",&a[i]);
    dfs(1,true,true,0);
    dfs(1,false,true,0);
    printf("%d",ans);
}

正解(AC100分DP)

#include <cstdio>
#define rr register
int max(int a,int b)
{
    if(a>b)
    return a;
    return b;
}
int main()
{
    int p,a[150001],f[150001][2];
    scanf("%d",&p);
    for(rr int i=1;i<=p;i++)
        scanf("%d",&a[i]);
    f[1][0]=a[1];
    for(rr int i=1;i<=p;i++)
            {
                f[i][0]=max(f[i-1][1]+a[i],f[i-1][0]);
                f[i][1]=max(f[i-1][0]-a[i],f[i-1][1]);
        }
    printf("%d",f[p][0]);
}

Problem 3

1341. water(水流) (Standard IO)

时间限制: 1000 ms  空间限制: 131072 KB  具体限制  
Goto ProblemSet

题目描述

全球气候变暖,小镇A面临水灾。于是你必须买一些泵把水抽走。泵的抽水能力可以认为是无穷大,但你必须把泵放在合适的位置,从而能使所有的水能流到泵里。小镇可以认为是N * M的矩阵。矩阵里的每个单元格都是一个‘a’- ‘z’小写字母,该小写字母表示该格子的高度,字母大的表示该单元格比较高,反之,表示该格子高度比较低。当前单元格的水可以流到上、下、左、右四个格子,但必须满足这些格子的高度是小于或者等于当前格子的高度。现在,给你一些N * M的矩阵,你至少要买多少个泵,才能把所有格子的水都能被抽走?

 

输入

 多组测试数据。

 第一行:K,表示有K组测试数据。 1 <= K <= 5.

 接下来有K组测试数据,每组测试数据格式如下:

     第一行:两个正数, N , M . 1 <= N, M <= 50,表示小镇的大小。

     接下来有N行,每行有M个小写字母,表示小镇的地图。

输出

共K行,每行对应一组数据。至少要买多少个泵,才能把所有格子的水都能抽走。

 

样例输入

 

样例输出

 
 

数据范围限制

 
 

提示

 















输入  

2

 5 5

 ccccc

 cbbbc

 cbabc

 cbbbc

 ccccc

 4 9

 cbabcbabc

 cbabcbabc

 cbabcbabc

 cbabcbabc

1

 11   11

 ccccccccccc

 caaaaaaaaac

 caaaaaaaaac

 caazpppzaac

 caapdddpaac

 caapdddpaac

 caapdddpaac

 caazpppzaac

 caaaaaaaaac

 caaaaaaaaac

 ccccccccccc

输出

1

2

 2

 

 
 
 
 
Fortuna OJ 项目
作者: moreDRD; 协力: twilightMcHobby
由 CodeIgniter / Bootstrap 驱动
Glyphicons 提供图标

思路:搜索(DFS,BFS均可)

代码实现:(DFS100分)

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int n,m;
char a[53][53];
bool bj[53][53];
int xi[]={0,0,-1,1};
int yi[]={1,-1,0,0};
void dfs(int x,int y)
{
    bj[x][y]=true;
    for(int i=0;i<4;i++)
    {
        int x1=x+xi[i];
        int y1=y+yi[i];
        if(x1<=n && x1>0 && y1<=m && y1>0 && bj[x1][y1]==false && a[x1][y1]>=a[x][y]){
        dfs(x1,y1);
    }
}}
int main()
{
    int k=0;
    scanf("%d",&k);
    while(k--)
    {
        memset(bj,false,sizeof bj);
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                cin>>a[i][j];
            }
        int ans=0;
        for(char c='a';c<='z';c++){
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){
                    if(bj[i][j]==false && a[i][j]==c)
                        {
                            dfs(i,j);
                            ans++;
                        }
                    }
                }
            }
        printf("%d\n",ans);
    }
}

 

Problem 4

题目描述

  Bessie受雇来到John的农场帮他们建立internet网络。农场有 N (2<= N <= 1,000)牛棚,编号为1..N。John之前已经勘测过,发现有 M (1<= M <= 20,000)条可能的连接线路,一条线路是连接某两个牛棚的。每条可能的线路都有一个建设费用 C (1<= C <=100,000)。John当然想花尽量少的钱,甚至克扣Bessie的工钱。

  Bessie发现了这点,很生气,决定给John捣乱。她要选择一些线路组成网,但费用却尽可能大。当然网络要能正常工作,也就是任意两个牛棚之间都是相互可以连通的,并且网络上不能有环,不然John会很容易发现的。

 请计算组建这种网络最多可能的费用。
 

输入

第一行:两个整数 N M

下面M行:每行3个整数 A,B,C。表示一个可能的线路要连接A、B两个牛棚,费用是C。

输出

只一行,一个整数,即花费最大的费用。如果不可能连接通所有牛棚,输出-1。
 

样例输入

 

样例输出

 
 

数据范围限制

 
 

提示

 















输入

5 8

1 2 3

1 3 7

2 3 10       

2 4 4

2 5 8

3 4 6

3 5 2

4 5 17

17 + 8 + 10 + 7 = 42

输出

42

 

 

 
 
 
 
Fortuna OJ 项目
作者: moreDRD; 协力: twilightMcHobby
由 CodeIgniter / Bootstrap 驱动
Glyphicons 提供图标

思路:最小生成树

代码实现:Unknow.

posted @ 2019-08-02 18:39  XYYXP  阅读(363)  评论(0编辑  收藏  举报