Problem G. Generators

本文探讨了一种算法竞赛中的优化问题,通过调整序列中最大值的位置,使得序列元素的总和不能被特定整数整除。代码示例使用了C++实现,详细展示了如何生成序列并检查其性质,同时提供了优化策略。

复杂度 基本上控制在 n^2.

这种最大值得问题,有点像随机数的感觉。 不知道怎么证明,为什么最多只需要置换一个 最大数就可以了。 这样得到的结果 就会等价于 取遍所有的情况。

 

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
#define rep(i,a,b) for(int i=a;i<b;++i)

const int N=10010;
struct node{
	int x,pos;
	node(int _x=0,int _pos=0){
		x=_x,pos=_pos;
	}
	bool operator<(const node& b)const{
		return x<b.x;
	}
};

vector<node> vec[N];
int vis[N],pos[N];


/*
2 3
1 1 1 6
2 4 0 5

2 2
0 7 2 8
2 5 0 6
*/

int main(){	

	freopen("generators.in","r",stdin);
	freopen("generators.out","w",stdout);
	LL n,k;
	scanf("%I64d %I64d",&n,&k);
	
	LL ans=0;
	LL x,x0,a,b,c;
	for(int i=1;i<=n;i++){
		scanf("%I64d %I64d %I64d %I64d",&x0,&a,&b,&c);
		vec[i].push_back(node(x0,0));
		
		fill(vis,vis+c+1,0);
		vis[x0]=1;
		
		for(int j=1;;j++){
			x=(a*x0+b)%c;
			if(vis[x])break;
			vis[x]=1;
			vec[i].push_back(node(x,j));
			x0=x;
		}	
		
		//printf("****\n");
		//for(int j=0;j<vec[i].size();j++)printf(" %d",vec[i][j].x);
		//printf("\n");
		
		sort(vec[i].begin(),vec[i].end());
		ans+=vec[i][vec[i].size()-1].x;
		pos[i]=vec[i][vec[i].size()-1].pos;
	}
	
	
	//printf("ans:%I64d\n",ans);
	
	LL tmp=ans,change=-1,pp=-1;
	if(ans%k!=0){
		printf("%I64d\n",ans);
		rep(i,1,n+1)printf("%d%c",pos[i],i==n?'\n':' ');
		return 0;
	}
	else{
		for(int i=1;i<=n;i++){
			int sz=vec[i].size();
			tmp-=vec[i][sz-1].x;
			for(int j=sz-1;j>=0;j--){
				if((tmp+vec[i][j].x)%k!=0){
					if(change==-1||tmp+vec[i][j].x>ans){
						change=i;
						pp=vec[i][j].pos;
						ans=tmp+vec[i][j].x;
					}
					break;
				}
			}		
			tmp+=vec[i][sz-1].x;
		}		
	}
	if(change!=-1){
		pos[change]=pp;
		printf("%I64d\n",ans);
		rep(i,1,n+1)printf("%d%c",pos[i],i==n?'\n':' ');
	}else{
		printf("-1\n");
	}
	
	return 0;
}

 

## Problem 5: Remainder Generator Like functions, generators can also be higher-order. For this problem, we will be writing `remainders_generator`, which yields a series of generator objects. `remainders_generator` takes in an integer `m`, and yields `m` different generators. The first generator is a generator of multiples of `m`, i.e. numbers where the remainder is 0. The second is a generator of natural numbers with remainder 1 when divided by `m`. The last generator yields natural numbers with remainder `m - 1` when divided by `m`. Note that different generators should not influence each other. > Hint: Consider defining an inner generator function. Each yielded generator varies only in that the elements of each generator have a particular remainder when divided by m. What does that tell you about the argument(s) that the inner function should take in? ```python def remainders_generator(m): """ Yields m generators. The ith yielded generator yields natural numbers whose remainder is i when divided by m. >>> import types >>> [isinstance(gen, types.GeneratorType) for gen in remainders_generator(5)] [True, True, True, True, True] >>> remainders_four = remainders_generator(4) >>> for i in range(4): ... print("First 3 natural numbers with remainder {0} when divided by 4:".format(i)) ... gen = next(remainders_four) ... for _ in range(3): ... print(next(gen)) First 3 natural numbers with remainder 0 when divided by 4: 4 8 12 First 3 natural numbers with remainder 1 when divided by 4: 1 5 9 First 3 natural numbers with remainder 2 when divided by 4: 2 6 10 First 3 natural numbers with remainder 3 when divided by 4: 3 7 11 """ "*** YOUR CODE HERE ***" ``` Note that if you have implemented this correctly, each of the generators yielded by `remainder_generator` will be infinite - you can keep calling next on them forever without running into a `StopIteration` exception.
05-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值