NOIP 提高组 飞扬的小鸟

9 篇文章 0 订阅
3 篇文章 0 订阅

Description

Flappy Bird是一款风靡一时的休闲手机游戏。玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙。如果小鸟一不小心撞到了水管或者掉在地上的话,便宣告失败。

现在小鸟们(n只)遇到了一个难题,他们遇到了一堵巨大的墙,墙上仅有m个洞供他们通过,由于小鸟们的体型不同且墙上洞的形状也不同,所以每种体型的鸟通过每个洞的时间都不同,鸟的体型共有n种,第i种体型的鸟通过第j个洞需要的时间记为T(i,j),且一个洞必须前一只鸟通过之后后一只鸟才能开始通过。

从时刻0开始,鸟开始通过,而每一只鸟的等待时间为从时刻0到自己已经通过洞的时间。现在知道了第i种体型的鸟有pi只,请求出使所有鸟都通过墙的最少的等待时间之和。

Data Constraint

这里写图片描述

Solution

看到这种题首先就想到了网络流(问:恩!?等等!!,网络流是NOIP提高组的?别吓我! 答:别问我,我也不知道,反正题目就摆在那,我在比赛时也别吓到了,搞到我第一时间就否决了网络流的想法,拼死去想了一个小时dp,毛都没有!!!)

我们考虑用费用流解决这道题。首先源点向第i种小鸟连一条流量为pi,费用为0的边,接着将每个洞拆成p个洞(p为小鸟总数)。每只小鸟分别向m* p个洞连一条流量为1,费用为 f(m,n)* 1,f(m,n)* 2,f(m,n)* 3,…… ,f(m,n)* p。m* p个洞分别向汇点连一条流量为1,费用为0的边。

由于有m*p=80000个洞,40种小鸟,总共会连3.2 106 ,条边,边数太过巨大!!!,所以我们考虑动态加边。具体操作为:我们会发现,对于第i个洞,不流第一个费用为f(i,j),反而流第二个费用为f(i,j) 2显然不优,所以我们对于第一个洞,只有流满第一个费用为f(i,j),才建流第二个费用为f(i,j)* 2边,即每种小鸟向新建的点连一条流量为1,费用为f(i,j)*2的边。

代码

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=6600000,maxn1=802;
int first[maxn],last[maxn],next[maxn],value[maxn],cost[maxn],d[maxn],dui[maxn],bz[maxn],a[maxn1][maxn1];
int n,m,num,x,i,t,j,k,l,ans,p,m1;
void lian(int x,int y,int z,int z1){
    last[++num]=y;value[num]=z;cost[num]=z1,next[num]=first[x];first[x]=num;
}
int pan(int x){
    if (x%m) return x%m;return m;
}
int pan1(int x){
    if (x%m) return x/m;return x/m-1;
}
int dg(int x,int sum){
    if (x==n+m*maxn1+1){
        ans+=d[0]*sum;
        return sum;
    }
    int t,k,q=sum,l;
    bz[x]=p;
    for (t=first[x];t;t=next[t])
        if (bz[last[t]]!=p && d[x]==d[last[t]]+cost[t] && value[t]){
            k=dg(last[t],min(q,value[t]));
            if (k){
                value[t]-=k;
                value[dui[t]]+=k;
                if (last[t]==n+m*maxn1+1){
                    for (i=1;i<=n;i++){
                        l=a[i][pan(x-n)]*(pan1(x-n)+2);
                        lian(i,x+m,1,l),lian(x+m,i,0,-l),dui[num]=num-1,dui[num-1]=num;
                    }
                    lian(x+m,n+m*maxn1+1,1,0),lian(n+m*maxn1+1,x+m,0,0),dui[num]=num-1,dui[num-1]=num;
                }
                q-=k;
                if (!q) break;
            }
        }
    return sum-q;
}
bool pan(){
    if (!p) return true;
    int i,j,t,k=maxn,l;
    for (i=0;i<=n+m*maxn1+1;i++)
        if (bz[i]==p)
            for (t=first[i];t;t=next[t])
                if (bz[last[t]]!=p && value[t]) k=min(k,d[last[t]]+cost[t]-d[i]);
    if (k==maxn) return false;
    for (i=0;i<=n+m*maxn1+1;i++)
        if (bz[i]==p) d[i]+=k;
    return true;
}
int main(){
//  freopen("data.in","r",stdin);
    scanf("%d%d",&n,&m);
    for (i=1;i<=n;i++)
        scanf("%d",&x),lian(0,i,x,0),lian(i,0,0,0),dui[num]=num-1,dui[num-1]=num;
    for (i=1;i<=n;i++)
        for (j=1;j<=m;j++){
            scanf("%d",&x);a[i][j]=x;
            lian(i,n+j,1,x),lian(n+j,i,0,-x),dui[num]=num-1,dui[num-1]=num;
        }
    for (i=n+1;i<=n+m;i++)
        lian(i,n+m*maxn1+1,1,0),lian(n+m*maxn1+1,i,0,0),dui[num]=num-1,dui[num-1]=num;
    while (pan()){
        p++;
        while (dg(0,maxn)) p++;
    }
    printf("%d\n",ans);
}
一、 本课题的研究意义 如今,戏风行的程度,是第一台电子戏机的研制者诺兰?布什纳尔先生始料不及的。在全世界最大的城市,直至最小的村庄,从纽约最辉煌的乐场,到高加索最小的乡镇儿童娱乐点,在千家万户,正在进行着千千万万这样的“战斗”,伴随着无数成功与失败,兴奋与懊丧。戏机带来了一个全球性的疯狂症,其他任何娱乐与之相比都望尘莫及。然而,究竟是什么原因使戏机如此风行呢? 在回顾了戏机发展简史之后,我们不难悟出,技术进步在戏机发展过程中起到了极大的促进作用。但是,技术进步绝不是戏机风行的唯一因素。随着终端设备开发能力的加强,作为娱乐终端的戏也得到了很大程度的发展。这也加速了戏在全球风行程度,所以对于戏的研究和设计具有很重要的意义,这也是本课题研究的意义所在。 用java语言来设计一个戏,不同于现在的大型网络戏和手机戏,也不同于其他的小型的单机控制程序,它对戏编写者对java语言特点认知、语法运用、工作模式、面向对象的理解的把握都提出了更高的要求,特别是在戏运行当中对外部按键的处理,各子程序的调用程,先后顺序等码的复杂程度也都是一般程序不能比的。可以这样说,能完整的编出戏,并可以稳定运行,会让我们对戏有一个更深刻的认识;对戏编写的难度有一个更切身的理解;对自己的编程能力及逻辑思维能力有一个很大的提高;再一次看到了java语言的面向对象性、动态性、高性能性,相信对java语言的学习也不无帮助。 二、课题的国内外开发动态 随着人们生活质量的不断提高以及个人电脑和网络的普及,人们的业余生活质量要求也在不段提高,选择一款好玩、精美、画面、品质优良的休闲戏已经成为一种行的休闲方式。可以说在人们的日常生活中,除了工作,学习,玩一款自己喜欢的戏正在成为一种时尚。所以,开发一款大家都比较喜欢的,高品质的休闲戏,将会收到人们的普遍欢迎。让人们在工作学习之余,享受戏的快乐,也是一款戏真正成功的意义。Java是一种简单的,面向对象的,分布式的,健壮的,安全的,可移植的,性能很优异的语言。Java是休闲互动戏开发的先导语言,使用java作为开发工具,是一种很理性的选择。 三、课题的基本内容 这是一款十分变态虐心的休闲戏。戏主打像素风格,粗看画面十分简陋,,戏中玩家需要点击屏幕操作一只小鸟在类似《超级马里奥》的绿色管道改变的数字中穿行,戏的方式是飞翔的小鸟带数字和2048戏的结合体,要是不幸小鸟带的数字碰到不对应的数字障碍,或者不点击屏幕就直接Game Over。戏里对小鸟的触碰判定非常严格,只要稍微节奏慢少许或者快了一点就会结束。由于湖完全没有道具辅助,很多时候开局连第一个障碍也过不了就不得不重来。虽然只是一款戏,玩法也不特别,不过却抓住了玩家输不起的心理,用超高难度吸引玩家来挑战。 四、拟需要解决的主要问题 飞翔的小鸟+2048小戏开发的技术难点主要两个方面:一是界面的布局;二是戏数据的安排。戏很注重玩家的感受,所以界面的布局很重要,其次数据的显示在一个戏的玩耍中也很重要,合理规划设计,开发出让玩家享受的戏。正确理解实际运行中玩家的感受,解决戏中模块的科学划分与结构织,更好更快的开发设计戏。 五、课题设计的实现方案 (1)本戏开发语言的选 飞翔的小鸟戏以纯java语言来开发编写。Java是由Sun Microsystems公司推出的Java面向对象程序设计语言(以下简称Java语言)和Java平台的总称。由James Gosling和同事们共同研发,并在1995年正式推出。Java最初被称为Oak,是1991年为消费类电子产品的嵌入式芯片而设计的。1995年更名为Java,并重新设计用于开发Internet应用程序。用Java实现的HotJava浏览器(支持Java applet)显示了Java的魅力:跨平台、动态Web、Internet计算。从此,Java被广泛接受并推动了Web的迅速发展,常用的浏览器均支持Javaapplet。另一方面,Java技术也不断更新。Java自面世后就非常行,发展迅速,对C++语言形成有力冲击。在全球云计算和移动互联网的产业环境下,Java更具备了显著优势和广阔前景。 (2)本戏开发工具的选择 飞翔的小鸟戏使用的开发工具是一个开放源代码的、基于Java的可扩展开发平台eclipse来开发实现。Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一服务,用于通过插件件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括Java开发工具(Java Development Kit,JDK)。Eclipse是著名的跨平台的自由集成开发环境(IDE)。最初主要用来Java语言开发,通过安装不同的插件Eclipse可以支持不同的计算机语言,比如C++和Python等开发工具。Eclipse的本身只是一个框架平台,但是众多插件的支持使得Eclipse拥有其他功能相对固定的IDE软件很难具有的灵活性。许多软件开发商以Eclipse为框架开发自己的IDE。 六、研究方法 该毕业设计采用的研究方法主要有文献法和调查法。该毕业设计具体功能的获取过程主要使用文献法和走访调查法,通过网络调查和查阅网络资料来具体确定该软件的功能需求细节;在软件开发过程中,解决技术问题使用的方法是文献法,通过查阅课本、图书馆资料和网络在线文献等,解决在软件开发过程中的技术问题,比如数据库、建模工具的使用、软件测试等。 七、选题的特色及创新点 选题的特色:本毕业设计的开题经过走访调查和文献查阅等多种方式,基本可以与现实的需求相一致,并能体现用所学的知识和计算机技术解决实际问题。 选题的创新点:该选题采用的均是计算机成熟的技术,在计算机技术方面并没有体现创新点,但是通过完成该毕业设计,可以使得自己对计算机软件开发由更深的认识,积极培养自己的创新意识。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值