蓝桥杯- 算法训练-Beaver's Calculator

                                                         算法训练 Beaver's Calculator 

 时间限制:3.0s   内存限制:256.0MB
问题描述
  从万能词典来的聪明的海狸已经使我们惊讶了一次。他开发了一种新的计算器,他将此命名为"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, 1xiyimi (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。

思路:由于顺序不可逆,每个科学家的最小“坏对”是确定的,将所有科学家的“坏对”记为 aans ,aans的最大值即为 ans。 我们可以将“坏对”较少的科学家的问题 往 最多的科学家的问题 中插入即可。注意:1)long long  2)要中间逐层排序输出,不能在最后全部输出。

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define REP(i,k,n) for(int i=k;i b.num;                       // 按消耗资源量从小到大排序   }}now,nex;priority_queueque;                       //  用队列实现排序输出int main(){   int n;   scan(n);   int sum = 0;   REPP(i,1,n){      scan(k1[i]);                             //k1[i] 第i个科学家的问题数 k2[i]第i个科学家已经处理的问题数      scann(a[i],x[i]);                        //a[i]  第i个科学家当前问题消耗的资源      scann(y[i],m[i]);      sum+=k1[i];                              //用 sum记录总问题数   }   bool flag = 0;   if(sum <= 200000) flag =1;                  //如果总问题数大于 200000 不用输出   int ans = 0;                                 //记录 所有科学家的“坏对”中最大的那个   REPP(i,1,n){   int aans = 0;                                 //科学家的坏对   LL kk,aa;   kk=1;aa=a[i];      while(kk < k1[i]){      LL w = (aa * x[i] + y[i]) % m[i];      if(w < aa) aans++;                          //从大变小 即一个 “坏对”      aa = w;      kk++;   }   ans = max(aans,ans);   }   cout<= now.num && k2[i] < k1[i]){ //每位科学家的问题一层一层进行处理,即当 a[i] < now.num,出现“坏对”停止   now.num = a[i]; if(flag) que.push(now); //如果要输出,则入队 tol++; k2[i]++; a[i] = (a[i] * x[i] + y[i]) % m[i]; //求出下一个要解决问题所需要的资源量 a[i]  }  }  }  if(flag){   while(!que.empty()){ //一层一层“坏对”进行处理,从而实现问题的插入      now = que.top(); que.pop();  cout<
 

你可能感兴趣的:(ACM-模拟)