蓝桥杯练习系统— 算法训练 Beaver's Calculator

问题描述

  从万能词典来的聪明的海狸已经使我们惊讶了一次。他开发了一种新的计算器,他将此命名为"Beaver‘s Calculator 1.0"。它非常特别,并且被计划使用在各种各样的科学问题中。
  为了测试它,聪明的海狸邀请了n位科学家,编号从1到n。第i位科学家给这个计算器带来了 ki个计算题。第i个科学家带来的问题编号1到n,并且它们必须按照编号一个一个计算,因为对于每个问题的计算都必须依赖前一个问题的计算结果。
  每个教授的每个问题都用一个数 ai,?j? 来描述,i(1≤i≤n)是科学家的编号,j(1≤j≤ ki )是问题的编号, ai,?j? 表示解决这个问题所需资源单位的数量。
  这个计算器非常不凡。它一个接一个的解决问题。在一个问题解决后,并且在下一个问题被计算前,计算器分配或解放资源。
  计算器中最昂贵的操作是解放资源,解放远远慢于分配。所以对计算器而言,每一个接下来的问题所需的资源不少于前一个,是非常重要的。
  给你关于这些科学家所给问题的相关信息。你需要给这些问题安排一个顺序,使得“坏对”尽可能少。
  所谓“坏对”,就是相邻两个问题中,后一个问题需求的资源比前一个问题少。别忘了,对于同一个科学家给出的问题,计算它们的相对顺序必须是固定的。

输入格式

  第一行包含一个整数n,表示科学家的人数。接下来n行每行有5个整数,kiai,?1, xiyimi (0?≤?ai,?1?<?mi?≤?109, 1?≤?xi,?yi?≤?109) ,分别表示第i个科学家的问题个数,第1个问题所需资源单位数,以及3个用来计算 ai,?j 的参量。ai,?j?=?(ai,?j?-?1?*?xi?+?yi)mod mi。

输出格式

  第一行输出一个整数,表示最优顺序下最少的“坏对”个数。
  如果问题的总个数不超过200000,接下来输出  行,表示解决问题的最优顺序。每一行两个用空格隔开的整数,表示这个问题所需的资源单位数和提供这个问题的科学家的编号。

样例输入

2
2 1 1 1 10
2 3 1 1 10

样例输出

0
1 1
2 1
3 2
4 2

数据规模和约定

  20%的数据 n?=?2, 1?≤?ki?≤?2000;
  另外30%的数据 n?=?2, 1?≤?ki?≤?200000;
  剩下50%的数据 1?≤?n?≤?5000, 1?≤?ki?≤?5000。

分析:找出所有科学家中坏对最多的一个科学家,坏对最多的科学家的坏对数max就为最优值,

证明:n个坏对就意味着可以把一个科学家所有的问题分成n+1个有序序列,

         例如:3 4 5 2 6 8 7 坏对数为2,那么可分为 (3 4 5)(2 6 8)(7)三个有序序列, 即三块,块号为 0 1 2;

5 6 3 5 8 7 2 坏对数为3, 那么可分为 (5 6)(3 5 8)(7)(2)四个有序序列 ,即4块,块号为0 1 2 3;

         我们同样可以把其余科学家的问题分为相应块数,那么我们把每个科学家对应相同块号的有序序列进行合并

(不能改变每个科学家问题的顺序)

因为本来每个序列就都是有序的,所有合并后的有序序列没有坏对,那么全部合并后,坏对数就为max

以上面数据为例进行合并(3 4 5 5 6)(2 3 5 6 8 8)(7 7)(2 ) 坏对数为3

因为每个科学家的问题顺序不能改变,那么最优值一定大于等于max,所以max一定为最优解;

代码:

#include<iostream>
#include<algorithm>
using namespace std;
const int MAX_N = 200000+100;
struct type{ int t, a, i; } d[MAX_N];
int n;
int tot = 0, ans = 0;

bool compare(type x, type y) {
    if(x.t == y.t)
        return (x.a < y.a || (x.a == y.a && x.i < y.i));
    else
        return x.t < y.t;
}
int main() {
    cin >> n;
    for(int i = 1; i <= n; i++) {
          long long k, a, x, y, m;
        cin >> k >> a >> x >> y >> m;
        int t = 0;
        long long b;
        for(int j = 0; j < k; j++) {
            if(tot < 2e5) d[tot++] = (type){t, a, i};
            b = (a*x+y)%m;
            if(b < a && j != k-1) t++;
            a = b;
        }
        ans = max(ans, t);
    }
    cout << ans << endl;
    if(tot < 2e5) {
        sort(d, d+tot, compare);
        for(long long i = 0; i < tot; i++)
        cout << d[i].a << " " << d[i].i << endl;
    }
    return 0;
}

蓝桥杯练习系统— 算法训练 Beaver's Calculator

原文地址:https://www.cnblogs.com/kindleheart/p/8422572.html

时间: 2024-11-05 17:32:51

蓝桥杯练习系统— 算法训练 Beaver's Calculator的相关文章

蓝桥杯练习系统—算法训练 P1102

第一部分:题目 定义一个学生结构体类型student,包括4个字段,姓名.性别.年龄和成绩.然后在主函数中定义一个结构体数组(长度不超过1000),并输入每个元素的值,程序使用冒泡排序法将学生按照成绩从小到大的顺序排序,然后输出排序的结果. 输入格式:第一行是一个整数N(N<1000),表示元素个数:接下来N行每行描述一个元素,姓名.性别都是长度不超过20的字符串,年龄和成绩都是整型. 输出格式:按成绩从小到大输出所有元素,若多个学生成绩相同则成绩相同的同学之间保留原来的输入顺序.输入: 3 A

蓝桥杯练习系统—算法训练 s01串

第一部分:题目 问题描述 s01串初始为"0" 按以下方式变换 0变1,1变01 输入格式 1个整数(0~19) 输出格式 n次变换后s01串 样例输入 3 样例输出 101 数据规模和约定 0~19 第二部分:思路 循环+中间数组.有一点小小的技巧就是,0->1,1->01.就是都变成1,只不过原先是1的话在前面加一个0. 第三部分:代码 #include<iostream> #include<stdio.h> #include<string

蓝桥杯练习系统—算法训练 最小最大公倍数

问题描述已知一个正整数N,问从1~N中任选出三个数,他们的最小公倍数最大可以为多少. 输入格式输入一个正整数N. 输出格式输出一个整数,表示你找到的最小公倍数.样例输入9样例输出504数据规模与约定1 <= N <= 106. 分析: 这个题的意思就是在1~N的范围内找三个数,使他们的最小公倍数在这个范围内的组合是最大的. 接下来先说一个结论:大于1的两个相邻的自然数必定互质. 而对于1~N的范围,肯定是 n*(n-1)*(n-2)的乘积最大.如果这三个数还两两互质的话那就最棒了. 如果n是奇

蓝桥杯练习系统—算法训练 未名湖畔的烦恼

问题描述 每年冬天,北大未名湖上都是滑冰的好地方.北大体育组准备了许多冰鞋,可是人太多了, 每天下午收工后,常常一双冰鞋都不剩. 每天早上,租鞋窗口都会排起长龙,假设有还鞋的m个,有需要租鞋的n个. 现在的问题是,这些人有多少种排法,可以避免出现体育组没有冰鞋可租的尴尬场面. (两个同样需求的人(比如都是租鞋或都是还鞋)交换位置是同一种排法)输入格式 两个整数,表示m和n输出格式 一个整数,表示队伍的排法的方案数.样例输入3 2样例输出5数据规模和约定 m,n∈[0,18] 分析:枚举出所有情况

蓝桥杯练习系统算法提高 求最大值

问题描述 给n个有序整数对ai bi,你需要选择一些整数对 使得所有你选定的数的ai+bi的和最大.并且要求你选定的数对的ai之和非负,bi之和非负. 输入格式 输入的第一行为n,数对的个数 以下n行每行两个整数 ai bi 输出格式 输出你选定的数对的ai+bi之和 样例输入 5-403 -625-847 901-624 -708-293 413886 709 样例输出 1715 数据规模和约定 1<=n<=100 -1000<=ai,bi<=1000 思路: 讲道理好嘛~~自己

蓝桥杯练习系统--入门训练+基础练习

入门训练 <1>Fibonacci数列 问题描述  Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1. 当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少. 输入格式  输入包含一个整数n. 输出格式  输出一行,包含一个整数,表示Fn除以10007的余数. 说明:在本题中,答案是要求Fn除以10007的余数,因此我们只要能算出这个余数即可,而不需要先计算出Fn的准确值,再将计算的结果除以10007取余数,直接计算余数往往比先算出原数再取

蓝桥杯练习系统算法提高—最大乘积

最大乘积  问题描述 对于n个数,从中取出m个数,如何取使得这m个数的乘积最大呢? 输入格式 第一行一个数表示数据组数 每组输入数据共2行: 第1行给出总共的数字的个数n和要取的数的个数m,1<=n<=m<=15, 第2行依次给出这n个数,其中每个数字的范围满足:a[i]的绝对值小于等于4. 输出格式 每组数据输出1行,为最大的乘积. 样例输入 1 5 5 1 2 3 4 2 样例输出 48 思路:将输入的数据存入数组然后做升序排列.然后开始从末端循环,每次循环都求出正序前两个数字的积和

蓝桥杯练习系统——基础练习 十六进制转十进制

0.下载安装Opencv,当前版本为249. 1.下载Python,当前OPencv版本为249,不过其支持的最新版本的Python为2.7,所以可以下载276版本. 2.下载numpy,开始我使用了1.6,没有通过,错误如图.下载了最新的1.8.1版本. 3.将Opencv安装目录下opencv\build\python\2.7\x86中的cv2.pyd复制到python安装目录Lib\site-packages下. 4.找到opencv源文件内的draw.py运行. 蓝桥杯练习系统--基础练

蓝桥杯练习系统题解

转于:http://www.cnblogs.com/cshhr/p/3550014.html 蓝桥杯官网练习系统题解(非VIP) BEGIN-4(Fibonacci数列) 有递推公式,大家都知道用递推公式求,仅仅要记得在递推的时候同一时候取模求好 这里给一份另类代码,用矩阵高速幂求,事实上还有循环节 /* (1 1) * (Fn-1) = ( Fn )//矩阵相乘,将就着看吧 (1 0) (Fn-2) (Fn-1) (1 1) * (1 1) * (Fn-2) = ( Fn ) (1 0) (1