重拾ZOJ 一周解题

ZOJ 2734 Exchange Cards

题目大意:

给定一个值N,以及一堆卡片,每种卡片有一个值value和数量number。求使用任意张卡片组成N的方式。

例如N = 10 ,cards(10,2)(7,2)(5,3)(2,2)(1,5),则10 = 10,10 =7+3+1,10=5+5…

思路分析:

由于之前做过1204,知道这题就是赤裸裸的搜索,直接用dfs暴力即可求得。

可做的优化处理就是——这个过程是贪心Greedy的,先从大到小这样取过来,所以,可以做一步降序排列的预处理。

如上例:我选择了7,那么我就不会去选择10,因为加上10太大了,超出了N。

知识点总结:

1) DFS走法:沿着可行的解空间往前走;

dfs(index, number, sum, target);

2) 循环走法:选择下一个起点枚举;

dfs(++index, 1, sum, target);

代码:

#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
#include<fstream>
using namespace std;

struct Cards
{
    int num;
    int value;
    bool operator <(const Cards& card)const
    {
        return value > card.value;
    }
};

int totalCardsCount;
vector<Cards> inputValues;

void dfs(int index, int number, int sum, int target)
{
    if (sum == target) //记录总述
    {
        totalCardsCount++;
        return;
    }
    if (index == inputValues.size()) return; //长度

    //能加则加,deep ing ... ...
    if (sum + inputValues[index].value <= target && number <= inputValues[index].num)
    {
        sum += inputValues[index].value;
        number++;
        dfs(index, number, sum, target);
        number--;
        sum -= inputValues[index].value;
    }

    dfs(++index, 1, sum, target);
}

int main()
{
    //ifstream cin("2734.txt");
    int T, i, target;
    int c = 0;
    int n;
    bool first = true;
    while (cin >> target){
        if (!first)
        {
            cout << endl;
        }
        first = false;
        c = 1;
        cin >> n;
        inputValues.clear();
        int tmp;
        for (i = 1; i <= n; i++)
        {
            Cards cd;
            cin >> cd.value;
            cin >> cd.num;
            inputValues.push_back(cd);
        }
        std::sort(inputValues.begin(), inputValues.end());
        totalCardsCount = 0;
        dfs(0, 1, 0, target);
        cout << totalCardsCount << endl;
    }
    return 0;
}

ZOJ 1947 The Settlers of Catan

题目大意:

给出一个无向图,求这个无权无向图的最长路径——the longest path。即,在图中找一条边不重复(点可以重复)的路径,所得的路径的边的条数即为所求。

如:3个点,两条边,(0,1)(1,2),则the longest path 为2。

图的最大规模为25*25。

思路分析:

看到这题,试图去网上搜索最长路径的知识点,但是始终找不到有用的。最后,我将起点放在欧拉回路的概念上,然后又了解到哈密顿回路,得出一个结论,求最长路径比欧拉回路更为广泛。

不小心浏览到维基百科,知道这是一个NP问题,其算法只能是暴力枚举。更了解到如果是有向图的最长路径的话应该先做拓扑排序预处理。

于是,直接对每个点进行dfs搜索,每次保存最长路径即可。

知识点总结:

1) 欧拉回路:经过图中所有边一次仅一次且行遍所有顶点的回路。

2) 哈密顿回路:经过图中所有顶点一次仅一次的回路。

代码:

#include <stdio.h>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<cstring>
#include<fstream>
#include<list>
using namespace std;

int graph[26][26];
bool visited[26][26];

int theLongestPath;
void dfs(int root, int d)
{
    if (d > theLongestPath)
    {
        theLongestPath = d;
    }

    for (int i = 0; i < 26; i++)
    {
        if (root == i) continue;
        if (graph[root][i] == 1 && visited[root][i] == 0)
        {
            visited[root][i] = visited[i][root] = 1;
            ++d;
            dfs(i, d);
            --d;
            visited[root][i] = visited[i][root] = 0;
        }
    }
}

int main1947()
{
    //fstream cin("1947.txt");
    int n, m;
    while (cin >> n >> m)
    {
        if (n == 0 && m == 0)break;
        memset(graph, 0, sizeof(graph));

        int start, end;
        for (int i = 0; i < m; i++)
        {
            cin >> start >> end;
            graph[start][end] = graph[end][start] = 1;
        }

        theLongestPath = 0;
        for (int i = 0; i < n; i++)
        {
            memset(visited, 0, sizeof(visited));
            dfs(i, 0);
        }
        cout << theLongestPath << endl;

    }
    return 0;
}

ZOJ 1978 Assistant Required

题目大意:

给定一个队列,2,3,。。。n,每次取队首元素作为幸运元素,然后将其后的每隔i个给拖出去干活。比如,第一次2是幸运的,4,6,8…就要干活;第二次3是幸运的,9,15,21。。。就要去干活。。。

求第K个幸运数字。

思路分析:

从2写道20的序列分析,发现和素数很像,甚至就做成了素数表。

但当测试第20个幸运数时,Sample Out给出的是83,我打出来的是71(还是73,具体忘了),发现错了,于是再分析之下,发现和素数表有点区别。

素数表:每次去除i的倍数;

幸运数字(暂且这么称吧)表:每次去除每隔i的数。

修改之,即可。

知识点总结:

1) 素数表;

代码:

#include<iostream>
#include<vector>
#include<map>
#include<string>
#include<algorithm>
#include<fstream>
using namespace std;

const int MAX_Prime = 3001;
const int SEARCH_INT = 34000;

int prime_like[MAX_Prime];
bool is[SEARCH_INT];

void make_prim_table()
{
    for (int i = 0; i < MAX_Prime; i++)
    {
        is[i] = 0;
    }
    int num = 1;
    for (int i = 2; i < SEARCH_INT; i++)
    {
        if (is[i] == 1) continue;
        if (is[i] == 0)
        {
            prime_like[num++] = i;
            if (num == MAX_Prime) break;
        }
        if (i == 2)
        {
            for (int k = i; k < SEARCH_INT; k += i)
            {
                is[k] = 1;
            }
        }
        else
        {
            int number = 0;
            for (int k = i + 1; k < SEARCH_INT; k++)
            {
                if (is[k] == 0)  //已经出队
                {
                    if (++number == i)
                    {
                        is[k] = 1;
                        number = 0;
                    }
                }
            }
        }
    }
}

int main1978()
{
    make_prim_table();
    //fstream cin("1978.txt");
    int n;
    while (true)
    {
        cin >> n;
        if (n == 0)break;
        cout << prime_like[n] << endl;
    }
    return 0;
}

Acceptted is the best thing for you ~

时间: 2024-08-08 21:55:56

重拾ZOJ 一周解题的相关文章

【重拾】数据结构之一

前言 久违来一发,回来学校也都两周了,想想也该定下来学学点什么了,突然发现以前学的好像都已经忘的差不多了,而且以前学的也学得云里雾里,所以今天我要重拾数据结构. 何为数据结构 数据是描述客观事实的数和字符的集合,人们通常以数据元素作为数据的基本单位,比如52班的每个学生记录都是一个数据元素数据项是具有独立含义的最小数据单位. 数据结构是指所有数据元素已经数据元素之间的关系数据结构包括以下几个方面:    1.数据元素之间的逻辑关系,即数据的逻辑结构,它是数据结构在用户面前呈现的形式    2.数

重拾linux

重拾linux 起因 因为想重拾起linux,同时需要用docker起几个镜像,用来学习网络知识.本来想直接去阿里云上买,后来一想自己机器上,起一个linux是个不错的选择,毕竟不花钱! 还可以用来做本地测试,学习使用linux.docker等.记录下过程,防止以后忘记!(所以不会涉及具体的安装步骤) 下载 到网易开源镜像站,挑选一个linux下载.我安装linux只要是为了学习运维方面的知识,同时用于进行网络知识方面的实践.如果你跟我一样,推荐Ubuntu server版本,纯字符界面,就跟一

重拾qt

最近公司又接了一个煤矿的项目,要写个小程序摘取数据,我是公司唯一c++程序员,本来搞ios搞好好的,现在又得重拾半年没摸得qt了.呵呵...呵呵呵. 这里只记录这次小程序的一些小的总结吧.. 1.中文字符: 函数:把一般字符串转为中文字符串: //中文处理 QString mysqlServerTs:: handleTheChinesCode(const char*words){ QTextCodec* tc = QTextCodec::codecForLocale(); return tc->

重拾梦想,做更好的自己

亥时,就寝,忽入空灵,甲申年出师已历一纪,诸多记忆电光石火逐一闪现.时年家贫无靠,生计无着,每日波奔却心系梦想,虽日日身疲体倦,却每以<孟子·告子下>篇中名句“天降大任于斯人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行指乱其所为,所以动心忍性,曾益其所不能也”以慰寸心,类比篇中清史名人,胸中满溢浩然正气,行事尽显峥嵘:历12载,生活稳定,已婚并育一女,四老体健而心宽,内子贤而持家,小女伶俐活泼,此三项尽得,可谓得意了. 然忆及往昔践行之路与现时行走之途,高下立判,原所行皆可日日前行,步步

重拾C/C++基础

1.复制指针时只复制指针中的地址,而不会复制指针指向的对象2.解决护栏柱错误的根本 是 从思想认知上搞定. 数组的序号为偏移量.  也即: 数组的第一个元素为arrName[0],其偏移量为03.使用strcpy函数时要注意,若是源串的长度大于目标串的长度,将会覆盖缓冲区后面的内容  所以尽量使用strncpy来替代strcpy4.数组可以使一维或者是多维.只要数组包含的元素为内置类型或者有默认构造函数的类,就可以初始化5.数学运算符有5个: +(加) -(减) *(乘) /(除) %(求模)6

重拾算法(5)——最小生成树的两种算法及其对比测试

重拾算法(5)——最小生成树的两种算法及其对比测试 什么是最小生成树 求解最小生成树(Minimum Cost Spanning Tree,以下简写做MST)是图相关的算法中常见的一个,用于解决类似如下的问题: 假设要在N个城市之间建立通信联络网,那么连通N个城市只需N-1条线路.这时自然会考虑这样一个问题:如何在最节省经费的前提下建立这个通信网. 在任意两个城市间都可以设置一条线路,相应地都要付出一定的经济代价.N个城市之间最多可能设置N(N-1)/2条线路,那么如何在这些线路中选择N-1条,

[java]基础重拾

7.17 重新学习了包管理 对于没有使用package打包的类,归到默认包.使用其他包名打包类,必须在工程文件夹下新建对应包名的目录.比如 package com.tencent.demo 则需要在工程文件夹下,新建名为com的文件夹,并在com文件夹下新建tencent文件夹,再简历demo文件夹,依次类推. [java]基础重拾

【玩转SQLite系列】(一)初识SQLite,重拾sql语句

转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53230842 本文出自[DylanAndroid的博客] [玩转SQLite系列](一)初识SQLite,重拾sql语句 SQLite由于是一个轻型的嵌入式的数据库,被应用于Android系统当中.在Android开发中 我们难免会用到SQLite数据库.接下来用一系列的文章来数据一下SQLite数据库. 一.认识SQLite 1.什么是SQLite SQLite,是一款轻型

编程成长日记——重拾C语言

人生总是需要一个契机才会去改变,其实与其说是契机,也不过是自己再给自己一次机会而已. 重拾C语言,我决定再给自己一次机会,不知道多年以后的我再次翻看这篇博客的时候会是怎样的心情,会不会记得当下身为大三狗的我终于想要告别一事无成,一无所获,一败涂地的颓废而不自知的大学生活,我不想说是为了理想而奋斗,更不是为了中华崛起,只是为了我自己,仅此而已. 感谢比特,给我一次改变的机会. 从零开始学起C语言. --------------------------------------煽情分割线-------