2022“杭电杯”中国大学生算法设计超级联赛(2)题解

这篇博客探讨了一道编程题目,涉及寻找整数n的分解,使得7a+31b+365c=n时,a+b+c的最小值。通过分析同余性质,作者提出了利用count函数处理n小于365的情况,并为n大于等于365的情况建立了解决方案。代码实现中展示了如何计算最小和并处理特殊情况。
摘要由CSDN通过智能技术生成

1012 Luxury cruise ship

s题意,给一个n 若存在a,b,c满足7a+31b+365c=n,求a+b+c的最小值s,否则输出-1

思路:要使得a+b+c的值最小,应使得c尽可能的大.容易想到,s(n)=s(365+n)-1 (前提是s(n)存在)

如果能得到i∈[1,365)的所有解s(i),那么对于所有n>0的解都可以算到。但显然存在很多的i满足s(i)=-1。我们可以设计一个函数count(x)处理n<365时的情况,再对n>=365的情况另外考虑

详细细节见代码

AC代码:

#include <stdio.h>
typedef long long ll;
int g[7]={0,5,3,1,6,4,2};
//31*0%7=0;
//31*5%7==1;
//31*3%7==2...
ll count(ll n);
int main()
{
	ll t;
	scanf("%lld",&t);
	ll coins;
	ll a[365]={0};
	//储存365到729的结果。根据同余的知识, 可知n>=7*31(不一定是最小的)时,7*a+31*b一定有非负数解,
	//从count函数也可以看出,给的n>=7*31时,a,b>=0. 所以a∈[365,730)时都是有解的 
	for(ll i=0;i<365;i++){
		if(count(i)==-1){
			a[i]=count(i+365);
		}
		else{
			a[i]=count(i)+1;
		}
	}
	for(ll i=0;i<t;i++){
		scanf("%lld",&coins);
		if(coins<365){
			printf("%lld",count(coins));
		}
		else if(coins>=365&&coins<730){
			printf("%lld",a[coins%365]);
		}
		else{
			ll mod=coins%365;
			ll t=(coins-mod)/365;
			t--;
			
			printf("%lld",t+a[mod]);
		}          
		putchar('\n');  
	}
}
ll count(ll n){//对n%7的值进行分析,g[n%7]表示需要的31最小数量 
	ll a=0,b=0;
	b=g[n%7];
	a=(n-31*b)/7;
	if(b*31>n) return -1;//意味着a<0 
	if(a>=31){//例如a=50,b=5,显然a=50-1*31=19,b=5+1*7=12是更最的解。 
		b+=7*(a/31);
		a%=31;
	}
	return a+b;
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值