算法训练(二)

1.zoj-4049

简单的进程模拟,大部分情况下可以直接出答案,当进入死循环的时候,不难发现,循环中所得值会出现重复,因此可视重复为死循环的标志,使用一个bool数组进行标记即可,代码如下:

#include <iostream>

#include<cstring>
using namespace std;

const int N = 10100;
const int Mod = 256;

bool dp[N][257];
struct node {
    char op[4];
    int v, k;
}p[N];

bool check(int pos, int num)
{
    if (dp[pos][num]) return false;
    else return true;
}

int main()
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        memset(p, 0, sizeof(p));
        memset(dp, false, sizeof(dp));
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++)
        {
            scanf("%s", p[i].op);
            if (strcmp(p[i].op, "add") == 0) scanf("%d", &p[i].v);
            else scanf("%d%d", &p[i].v, &p[i].k);
        }
        int num = 0, pos = 1;
        bool flag = true;
        while (pos <= n && flag)
        {
            flag = check(pos, num);
            if (!flag) continue;
            dp[pos][num] = true;
            if (strcmp(p[pos].op, "add") == 0)
            {
                num = (num + p[pos].v) % Mod;
                pos++;
            }
            else if (strcmp(p[pos].op, "beq") == 0)
            {
                if (num == p[pos].v) pos = p[pos].k;
                else pos++;
            }
            else if (strcmp(p[pos].op, "bne") == 0)
            {
                if (num != p[pos].v) pos = p[pos].k;
                else pos++;
            }
            else if (strcmp(p[pos].op, "blt") == 0)
            {
                if (num < p[pos].v) pos = p[pos].k;
                else pos++;
            }
            else
            {
                if (num > p[pos].v) pos = p[pos].k;
                else pos++;
            }
        }
        if (flag) puts("Yes");
        else puts("No");
    }
    return 0;
}

2.zoj-4057

通过分析可得,最短的序列的二进制位一定是要相同的,这样最高位异或后皆为0,一定会比序列中最小的值还要小,所以只要求出二进制位数相同的最多的序列即可,代码如下:

#include<cstdio>
#include<cmath>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
int a[35];
void init()
{
    for (int i = 1; i <= 30; i++)
    {
        a[i] = (int)(pow(2, i));
    }
}
int main()
{
    int t;
    init();
    scanf_s("%d", &t);
    while (t--)
    {

        int n;
        scanf_s("%d", &n);
        int sum[35] = { 0 };
        for (int i = 0; i<n; i++)
        {
            int x;
            scanf_s("%d", &x);
            for (int j = 1; j <= 30; j++)
            {
                if (x<a[j])
                {
                    sum[j]++;
                    break;
                }
            }
        }
        int ans = -1;
        for (int i = 1; i <= 30; i++)
        {
            ans = max(ans, sum[i]);
        }
        printf("%d\n", ans);
    }
    return 0;
}

3.zoj-4056

可先画时间轴,不难发现,整个时间轴其实是由多次循环得到的,于是我们可以先求出两个时间的最小公倍数确定循环,因为每次灯泡只维持(v+0.5)s,所以将一个循环中的两个时间的倍数压进数组排序去重,灯没亮的时候要花一次去按灯,循环中的算出来后还要跑一次多出来的不在循环中的即可,代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
#define int long long
vector<long long>V;

int gcd(int a, int b)
{
    if (b == 0)
        return 1;
    else
        return gcd(b, a%b);
}

int main()
{
    int T;
    scanf("%lld", &T);
    while (T--)
    {
        int a, b, c, d, v, t;
        scanf("%lld%lld%lld%lld%lld%lld", &a, &b, &c, &d, &v, &t);
        long long te = gcd(a, c);
        long long lcm = a * c / te;
        V.clear();
        for (int i = 0; i <= lcm; i += a) V.push_back(i);
        for (int i = 0; i <= lcm; i += c) V.push_back(i);
        sort(V.begin(), V.end());
        V.erase(unique(V.begin(), V.end()), V.end());
        int tmp = 0;
        for (int i = 1; i < V.size(); i++)
        {
            if (V[i] - V[i - 1] > v) tmp++;
        }
        long long ans = (t / a) * b + (t / c) * d + b + d - 1;
        long long cur = t / lcm;
        ans = ans - cur * tmp;
        long long la = t % lcm;
        for (int i = 1; V[i] <= la; i++)
        {
            if (V[i] - V[i - 1] > v) ans--;
        }4
        cout << ans << endl;
    }
}

原文地址:https://www.cnblogs.com/KasenBob/p/9991658.html

时间: 2024-10-11 02:07:05

算法训练(二)的相关文章

蓝桥杯算法训练&lt;二&gt;

一.最小乘积(基本型)[这个题需要认真阅读试题,内容量较大,刚开始的时候,由于练习系统上给出的输入输出的格式有问题,没看懂,最后在MikCu的博客上看到了正确的格式,参考了代码,最终得到正确的结果.为了让结果最小,可以先分别对两组数进行排序,然后对其中的一组数据逆序,逆序后,把两组数据最大的与最小的相乘,最后求得的和最小!] 问题描述 给两组数,各n个. 请调整每组数的排列顺序,使得两组数据相同下标元素对应相乘,然后相加的和最小.要求程序输出这个最小值. 例如两组数分别为:1 3 -5和-2 4

蓝桥杯 算法训练 ALGO-124 数字三角形

算法训练 数字三角形 时间限制:1.0s   内存限制:256.0MB 问题描述 (图3.1-1)示出了一个数字三角形. 请编一个程序计算从顶至底的某处的一条路 径,使该路径所经过的数字的总和最大. ●每一步可沿左斜线向下或右斜线向下走: ●1<三角形行数≤100: ●三角形中的数字为整数0,1,-99: . (图3.1-1) 输入格式 文件中首先读到的是三角形的行数. 接下来描述整个三角形 输出格式 最大总和(整数) 样例输入 573 88 1 02 7 4 44 5 2 6 5 样例输出 3

蓝桥杯 算法训练 ALGO-57 删除多余括号

算法训练 删除多余括号 时间限制:1.0s   内存限制:512.0MB 问题描述 从键盘输入一个含有括号的四则运算表达式,要求去掉可能含有的多余的括号,结果要保持原表达式中变量和运算符的相对位置不变,且与原表达式等价,不要求化简.另外不考虑'+' '-'用作正负号的情况,即输入表达式不会出现(+a)或(-a)的情形. 输入格式 表达式字符串,长度不超过255, 并且不含空格字符.表达式中的所有变量都是单个小写的英文字母, 运算符只有加+减-乘*除/等运算符号. 输出格式 去掉多余括号后的表达式

蓝桥杯 算法训练 ALGO-36 传纸条

算法训练 传纸条 时间限制:1.0s   内存限制:512.0MB 问题描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的是,他们可以通过传纸条来进行交流.纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n).从小渊传到小轩的纸条只可以向下或者向右传递,从小轩传给小渊的纸条只可以向上或者向左传递. 在

ACM训练二C题

kmp对我真无奈,我对kmp真苦恼.就是个算法嘛,我以为凭我脖子上的东西可以搞定,现在好了--搞得我头都大了.要我写个啥next的值,五个字:那都不是事.一到啥实际应用吧,我意识不行了,搞不清next到底有什么作用,能干什么.就好比见到了二分啊-- 此题的意思呢,我弄了很久,其实是找相同串,比如ACMACMACMACMACMA,从后往前看next就行了,比如最后一个next[15] = 13,代表前13个字符串和后13位相同,直接用总长16 - 13 = 3,为一个解,接下来看next[13]了

蓝桥杯:算法训练之最大最小公倍数

算法训练 最大最小公倍数 时间限制:1.0s   内存限制:256.0MB 问题描述 已知一个正整数N,问从1~N中任选出三个数,他们的最小公倍数最大可以为多少. 输入格式 输入一个正整数N. 输出格式 输出一个整数,表示你找到的最小公倍数. 样例输入 9 样例输出 504 数据规模与约定 1 <= N <= 106. 注:贪心,从最大的三个数开始考虑,如果最大的数为奇数,那么相邻的三个数中有两个奇数,最大公约数为1,最小公倍数就为n(n-1)(n-2). 如果为偶数,那么往后移,考虑n(n-

63天算法训练详细说明

目的 熟悉新近学习的编程语言各种语法糖,最大化的精简代码. 复习基本数据结构和基本算法,提高代码效率. 训练持久力. 说明 所有的算法题目来源于LeetCode,版权归官方所有. 知乎:大家是如何刷LeetCode的? Github:详尽的LeetCode题解 Github:动画演示LeetCode题目 常用数据结构和算法的动态可视化 个人训练 截至2020年2月26日时,基础题目共有1257道,按一个随笔3道题目为例,预计花费时间1257/3=419天,大概是1年3个月,当然某些时候状态好或者

蓝桥杯——算法训练之乘积最大

问题描述 今年是国际数学联盟确定的"2000--世界数学年",又恰逢我国著名数学家华罗庚先生诞辰90周年.在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZ也有幸得以参加.活动中,主持人给所有参加活动的选手出了这样一道题目: 设有一个长度为N的数字串,要求选手使用K个乘号将它分成K+1个部分,找出一种分法,使得这K+1个部分的乘积能够为最大. 同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子: 有一个数字串:312, 当N=3,K=1时

蓝桥杯 算法训练 ALGO-125 王、后传说

算法训练 王.后传说 时间限制:1.0s   内存限制:256.0MB 问题描述 地球人都知道,在国际象棋中,后如同太阳,光芒四射,威风八面,它能控制横.坚.斜线位置. 看过清宫戏的中国人都知道,后宫乃步步惊心的险恶之地.各皇后都有自己的势力范围,但也总能找到相安无事的办法. 所有中国人都知道,皇权神圣,伴君如伴虎,触龙颜者死...... 现在有一个n*n的皇宫,国王占据他所在位置及周围的共9个格子,这些格子皇后不能使用(如果国王在王宫的边上,占用的格子可能不到9个).当然,皇后也不会攻击国王.

蓝桥杯 算法训练 ALGO-139 s01串

算法训练 s01串 时间限制:1.0s 内存限制:256.0MB 问题描述  s01串初始为"0"  按以下方式变换  0变1,1变01 输入格式  1个整数(0~19) 输出格式  n次变换后s01串 样例输入 3 样例输出 101 数据规模和约定  0~19 示例代码: 1 import java.util.Scanner; 2 3 public class Main { 4 static StringBuffer sb = new StringBuffer(); 5 public