蓝桥杯 ALGO-131 Beaver's Calculator

题意:把所有的科学家的题目进行输入,要求使得释放资源最少,而且使得科学家所有输入的题目的相对顺序不能改变。出现逆序对的原因是对之前的资源处理时,%m,所以可能会出现逆序对的情况。对于前面一个问题,就是按照输入的题目优化后所得到的逆序对是最少的,而且每个科学家输入的题目相对顺序不能变。所以当把所有的题目合并的时候,优化后的最少逆序对就是所有科学家中逆序对数最多的逆序对数,因为在合并所有的题目的时候,按照最大的逆序对数来划分段,然后在把其他的科学家的题目相对应的段插到一起,因为每个段都是有序的,所以插入进来后每个段也是有序的,所以优化后的逆序对数就是之前所有科学家的最大的逆序对数。

思路:首先会输入第一个数据,然后依次统计后面的情况,使用逆序对数来作为段的段号,当然会使用段号来进行排序,

主要是统计每个科学家的逆序对数以此作为段的数目,还有就是要统计总的题目数,超过200000的时候,就不用往数组里面添加了,(一定要判断,否则有一部分通不过),只统计总的逆序对数就可以了。

参考:https://blog.youkuaiyun.com/myfatmyfat/article/details/88205053

代码:

#include <iostream>
#include<algorithm>
#include<vector> 
typedef long long int LL;
#define N  200000
using namespace std;
struct node{
	LL section,res,index;//section(切段后的段号),res(所需资源号),index(科学家的编号) 
	node(){}
	node(LL s,LL r,LL i):section(s),res(r),index(i){}//构造函数 
}sc[210000]; 
bool com(node a,node b){ 
	if(a.section != b.section)return a.section < b.section;//断号小的排在前面,毕竟先输入 
	else if(a.res != b.res)return a.res < b.res;//同一段中所需资源越小,越靠前 
	else return a.index < b.index;//所有的都一样,则需要按照科学家的索引来排序 
} 
int main(int argc, char** argv) {
	LL n,cnt = 0,sumBad = 0;//sum保存的是所有科学家总的问题数目,sumBad表示总的逆序对数 
	cin>>n;
	for(int i=1;i<=n;i++){
		LL k,res,x,y,m,tem,badPair = 0;//badPair当前科学家的逆序对数 
		cin>>k>>res>>x>>y>>m;
		sc[cnt++] = node(badPair,res,i); //输入第一个所需资源数 
		for(int j=2;j<=k;j++){
			tem = (res*x+y)%m;//当前所需资源数
			if(tem < res) {//当发现逆序对时,段区要改变了,badPair充当了段区的索引 
				badPair++; 
			}
			if(cnt <= N){
				sc[cnt++] = node(badPair,tem,i);
			}  
			res = tem;//更新当前值 
		}
		sumBad = max(badPair,sumBad);
	} 
	printf("%d\n",sumBad);
	sort(sc,sc+cnt,com);
	if(cnt <= N){//小于N才打印,否则只打印逆序对数
		for(int i=0;i<cnt;i++){
			printf("%d %d\n",sc[i].res,sc[i].index);
		}	
	} 
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值