JUST第二界算法设计大赛题解

1、问题描述:

悠悠假期同叔叔一起去书店,他选中了六本书,每本书的单价(单位:元)分别为:3.1,1.7,2,5.3,
0.9 和7.2。不巧的是,叔叔只带了十几块钱,为了让悠悠高兴,叔叔同意买书,但提出了一个要求,要悠
悠从六本书中选出若干本,使得单价相加所得的和同10 最接近。请编程帮助悠悠解决这个问题。输出格
式:第一行输出1 个整数,表示组合方法数量;第二行开始,一行输出一种价格组合。

#include"cstdio"
#include"cmath"
#include"vector"
using namespace std;
double p[6]={3.1,1.7,2,5.3,0.9,7.2};
int a[6];
vector<double> vec[1<<12];
double maxn;
int cnt;
void solve()
{
    for(a[0]=0;a[0]<=1;a[0]++)
    for(a[1]=0;a[1]<=1;a[1]++)
    for(a[2]=0;a[2]<=1;a[2]++)
    for(a[3]=0;a[3]<=1;a[3]++)
    for(a[4]=0;a[4]<=1;a[4]++)
    for(a[5]=0;a[5]<=1;a[5]++)
    {
        double s=0;
        for(int j=0;j<6;j++)
        {
            s+=a[j]*p[j];
        }
        if(fabs(s-10)<maxn)
        {
            maxn=fabs(s-10);
            for(int i=0;i<cnt;i++)
            {
                vec[i].clear();//若最小值更新,则将结果清空
            }
            cnt=0;
        }
        if(fabs(fabs(s-10)-maxn)<0.000001)
        {
            for(int j=0;j<6;j++)
            {
                if(a[j]!=0)    vec[cnt].push_back(p[j]);
            }
            cnt++;
        }

    }
}
void print()
{
    printf("%d\n",cnt);
    for(int i=0;i<cnt;i++)
    {
        for(int j=0;j<vec[i].size();j++)
        {
            printf("%lf ",vec[i][j]);
        }
        printf("\n");
    }
}
int main()
{
    maxn=100;
    solve();
    print();
    return 0;
}

2、问题描述:

将1、2、3、4、5 和6 填入下表中,要使得每一列右边的数字比左边的数字大,每一行下面的数字比
上面的数字大。请编程计算共有几种填写方法?输出:第一行输出1 个整数,表示填写方法数量;第二行,
依次输出每种填写方式。

#include"cstdio"
#include"set"
#include"vector"
using namespace std;
int a[6]={1,2,3,4,5,6};
set<int> vec;
vector<int> ss[36*36*36];
int cnt;
bool check()
{
    for(int i=0;i<2;i++)
    {
        if(!(a[i+1]>a[i]&&a[i+3+1]>a[i+3]&&a[i+3]>a[i]))
        {
            return false;
        }
    }
    if(!(a[5]>a[2]))
    {
        return false;
    }
    return true;
}
void solve()
{
    for(a[0]=1;a[0]<=6;a[0]++)
    for(a[1]=1;a[1]<=6;a[1]++)
    for(a[2]=1;a[2]<=6;a[2]++)
    for(a[3]=1;a[3]<=6;a[3]++)
    for(a[4]=1;a[4]<=6;a[4]++)
    for(a[5]=1;a[5]<=6;a[5]++)
    {
        vec.clear();
        for(int j=0;j<6;j++)
        {
            vec.insert(a[j]);
        }
        if(vec.size()==6&&check())
        {
            for(int j=0;j<6;j++)
            {
                ss[cnt].push_back(a[j]);
            }
            cnt++;
        }
    }
}
void print()
{
    printf("%d\n",cnt);
    for(int i=0;i<cnt;i++)
    {
        for(int j=0;j<6;j++)
        {
            printf("%d ",ss[i][j]);
            if(j==2)    printf("\n");
        }
        printf("\n\n");
    }
}
int main()
{
    solve();
    print();
    return 0;
}

3、问题描述:

在一个旅馆中住着六个不同国籍的人,他们分别来自美国(US)、德国(GER)、英国(UK)、法国
(FRA)、俄罗斯(RUS)和意大利(ITA)。他们的名字叫A、B、C、D、E 和F。名字的顺序与上面的
国籍不一定是相互对应的。现在已知:
1)A 和美国人是医生。 2)E 和俄罗斯人是技师。
3)C 和德国人是技师。 4)B 和F 曾经当过兵,而德国人从未参过军。
5)法国人比A 年龄大;意大利人比C 年龄大。
6)B 同美国人下周要去西安旅行,而C 同法国人下周要去杭州度假。
请编程分析出A、B、C、D、E 和F 各是哪国人?(程序必须算法分析过程,不可直接输出结果)
输出格式:第一行输出A 是哪国人,第二行输出B 是哪国人......以此类推。(例如:A is US)

#include"algorithm"
#include"vector"
#include"string"
#include"iostream"
using namespace std;
int a[6]={0,1,2,3,4,5};
vector<string> ss;
bool check1()
{
    if(a[0]!=0&&a[0]!=1&&a[0]!=2&&a[0]!=4)
    {
        return true;
    }
    return false;
}
bool check2()
{
    if(a[1]==3)
    {
        return true;
    }
    return false;
}
bool check3()
{
    if(a[3]!=0&&a[3]!=1&&a[3]!=2)
    {
        return true;
    }
    return false;
}
bool check4()
{
    if(a[4]!=0&&a[4]!=2&&a[4]!=4)
    {
        return true;
    }
    return false;
}
bool check5()
{
    if(a[5]!=2)
    {
        return true;
    }
    return false;
}
void print()
{
    for(int i=0;i<6;i++)
    {
        string s="";
        switch(i)
        {
            case 0:{ s+=(‘A‘+a[i]);s+=" is US";break;}
            case 1:{ s+=(‘A‘+a[i]);s+=" is GER";break;}
            case 2:{ s+=(‘A‘+a[i]);s+=" is UK";break;}
            case 3:{ s+=(‘A‘+a[i]);s+=" is FRA";break;}
            case 4:{ s+=(‘A‘+a[i]);s+=" is RUS";break;}
            case 5:{ s+=(‘A‘+a[i]);s+=" is ITA";break;}
        }
        ss.push_back(s);
    }
    sort(ss.begin(),ss.end());
    for(int i=0;i<ss.size();i++)
    {
        cout<<ss[i]<<endl;
    }
}
int main()
{
    int ans=0;
    do{
        if(check1()&&check2()&&check3()&&check4()&&check5())
        {
            break;
        }
    }while(next_permutation(a,a+6));
    print();
    return 0;
}

4、问题描述:

扬扬喜欢滑雪,可是为了获得速度,滑的区域必须向下倾斜,扬扬想知道在一个区域中最长底滑坡。
区域由一个二维数组表示。数组的每个数字代表点的高度。下面是一个例子:
1 3 5 7
23 25 27 9
21 31 29 11
19 17 15 13
一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的
滑坡为31-25-3-1,长度为4。当然31-29-27-...-5-3-1 更长。事实上,这是最长的一条,长度为16。
输入:每组数据的第一行表示区域的行数R 和列数C(1 <= R,C <= 100)。下面是R 行,每行有C 个整数,
代表高度h,0<=h<=10000。
输出:输出最长区域的长度。

#include"cstdio"
#include"algorithm"
using namespace std;
const int MAXN=105;
int h[MAXN][MAXN];
int mp[MAXN][MAXN];
int n,m;
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
int rdfs(int y,int x)
{
    if(mp[y][x])    return mp[y][x];
    int k=0;
    for(int i=0;i<4;i++)
    {
        int ny=y+dy[i];
        int nx=x+dx[i];
        if(0<=ny&&ny<n&&0<=nx&&nx<m&&h[ny][nx]<h[y][x])
        {
            k=max(rdfs(ny,nx),k);
        }
    }
    return mp[y][x]=k+1;
}
int main()
{
    scanf("%d %d",&n,&m);
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++)    scanf("%d",&h[i][j]);}

    int ans=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++)    ans=max(rdfs(i,j),ans);}

    printf("%d\n",ans);

    return 0;
}
时间: 2024-12-26 04:53:44

JUST第二界算法设计大赛题解的相关文章

算法设计与分析 - 李春葆 - 第二版 - pdf-&gt;word v3

1 1.1 第1章─概论 2 3 1.1.1 练习题 4 1. 下列关于算法的说法中正确的有( ). 5 Ⅰ.求解某一类问题的算法是唯一的 6 Ⅱ.算法必须在有限步操作之后停止 7 Ⅲ.算法的每一步操作必须是明确的,不能有歧义或含义模糊 8 Ⅳ.算法执行后一定产生确定的结果 9 A. 1个 B.2个 C.3个 D.4个 10 2. T(n)表示当输入规模为n时的算法效率,以下算法效率最优的是( ). 11 A.T(n)= T(n-1)+1,T(1)=1 B.T(n)= 2n2 12 C.T(n)

数据结构与算法分析(六)——算法设计技巧

从算法的实现向算法的设计转变,提供解决问题的思路 1.贪心算法 一种局部最优算法设计思路,思想是保证每一步选择在当前达到最优.一个很常见的贪心算法案例是零钱找取问题. 调度问题:书上的调度问题比较简单,其目标是所有作业的平均持续时间(调度+运行)最短,无论是但处理器还是多处理器,最优解的方案总是按作业的长短排序进行调度.<计算机算法设计与分析>上的作业调度的目标是最后完成时间最小,这要稍微复杂一些. 霍夫曼编码:最优编码必定保持满树的性质,基本问题在于找到总之最小的满二叉树.最简单的霍夫曼编码

【转载】算法设计之五大常用算法设计方法总结

转载自http://blog.csdn.net/zolalad/article/details/11393915 算法设计之五大常用算法设计方法总结 一.[分治法]  在计算机科学中,分治法是一种很重要的算法.字面上的解释是"分而治之",就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题--直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)--等.任

AACOS:基于编译器和操作系统内核的算法设计与实现

AACOS:基于编译器和操作系统内核的算法设计与实现 [计算机科学技术] 谢晓啸 湖北省沙市中学 [关键词]: 编译原理,操作系统内核实现,算法与数据结构,算法优化 0.索引 1.引论 1.1研究内容 1.2研究目的 1.3研究提要 正文 2.1研究方法 2.2编译器部分 2.2.1从计算器程序中得到的编译器制作启示 2.2.2在编译器中其它具体代码的实现 2.2.3编译器中栈的高级应用 2.2.3编译器中树的高级应用 2.2.4编译器与有限状态机 2.3操作系统内核部分 2.3.1操作系统与底

“谁是大V”算法设计 (Map-Reduce TopN)

作业设计与资料 链接: http://pan.baidu.com/s/1o6MJTyi 密码: 628d 一.     作业要求   根据关注列表relsample.json文件,设计MapReduce算法得到被关注次数最多的前十人,即寻找谁是大V. 二.     算法设计   第一个Mapper用于解析json文件: 从relsample.json文件中解析出ids列表的内容,即每个人所关注的人的列表.输出的value为列表中的每一项,k为one. 对应的文件为\src\myMapper\re

第五届蓝桥杯全国软件设计大赛--2013年校内选拔赛Java题目

第五届蓝桥杯全国软件设计大赛 2013年校内选拔赛Java题目 一.考生注意: (1)[结果填空题]要求参赛选手根据题目描述直接填写结果.求解方式不限.不要求源代码. 把答案存入[考生文件夹]下对应题号的文件中即可. (2)[代码填空题]要求参赛选手在弄清给定代码工作原理的基础上填写缺失的部分,使得程序逻辑正确.完整.所填写的代码不超过一条语句(即中间不能出现分号). 把填空的答案(仅填空处的答案,不包括题面已存在的代码)存入[考生文件夹]下对应题号的文件中中即可. (3)[编程题]要求选手设计

第二篇 算法概述及复杂度

虽然本系列随笔是记录数据结构相关的内容,但是我们都知晓算法和数据结构是密不可分的.我们也可以时常看到一个公式“程序设计=数据结构+算法”.数据结构是研究数据之前的关系,以及数据在计算机中的存储形式,而算法是让数据通过一定的形式得到我们需要的结果.这其中包含各种的逻辑运算等. 提及算法,我们会自然的联想到一个关于数学牛人的故事:“高斯7岁那年开始上学.10岁的时候,一天,老师布置了一道题,1+2+3······这样从1一直加到100等于多少.高斯很快就算出了答案,起初高斯的老师布特纳并不相信高斯算

针对范围对的高效查找算法设计(不准用数组)

题目链接在:针对一群范围对的最快查找算法设计(不要用数组),是我目前遇到的一个较棘手的问题. 描述如下: 假如有一群范围对,格式为:<范围表示,该范围对应的结果值>,设计一个最快查找算法,使得给定一个值,输出该值所在范围对的结果值. 注意:范围对之间没有交集,即不可能存在<1, 10>和<2, 11>这样的两个范围对. 例如有以下几个范围对: <<1, 2>, 20> <<3, 37>, 27> <<48, 5

常用算法设计技术总结

算法,即计算的方法,使用计算的思想.方法.工具和技术来实现问题求解的思路和途径.计算机提供了计算的能力和硬件设施:算法则提供了计算的思想和软件技术,更好地发挥计算机的潜能. —— 引 有人说,算法无用,这种观点就如同盲人看不到花开就说世界上没有花一样,是一个长眼睛的人无论如何也难以接受的.举个简单的例子,假如你要对1000,000条记录进行排序,你的计算机每秒可处理1000,000 条记录, 那么, 如果你选择 O(nlogn)的快速排序,所花时间大约是 log2(1000000) = 20s,