Contest2657 - 2021ACM俱乐部后备营个人训练赛第4场 部分题解

ps:加乐大管家非让俺写~
只提供优质的思路&实现方法~ 建议初学者先先多学一些优质的写法和代码风格~

#define rep(i,j,n) for(ll i=j;i<=n;i++)
#define per(i,j,n) for(ll i=j;i>=n;i--)
#define pr(x) printf("%lld\n",x) 

 问题 F: 分蛋糕

思路:模拟即可,可以直接暴力选择每一个标准直接跑两层for,复杂度n^2,但考虑到可以依次从小到大选择,所以我们排个序,记个前缀和,每次选这个的时候,记录他前面的所有的值,和后面的和再记录一个左右的长度。   4ms


WZJ过生日了,他邀请了许多人来参加她的生日聚会,生日聚会中最重要的一件事情就是吃蛋糕了。WZJ共邀请了n个人,这些人的心里都想好了自己要多少克蛋糕。如果给他少了,他就会郁闷(没有吃到足够多的蛋糕)。如果给他多了,他也会郁闷(因为他不能浪费,需要把这些蛋糕都吃了,撑着了会不舒服)。一个人的郁闷指数为他想要的蛋糕克数与他实际得到的蛋糕克数之差的绝对值。WZJ想指定一个人想要的蛋糕克数作为标准,给每个人都是这么多蛋糕。聚会是件高兴的事情,同学们郁闷指数之和越小越好,现在他需要知道同学们的郁闷指数最低值是多少,请你编写程序帮他实现。
输入
共有两行:
第一行:为正整数n,表示参加聚会总共有n位同学。
第二行:为n个正整数(n<10000),表示每个人想要得到的蛋糕克数(<=1000)。
输出
只有一行:为输出所有人的郁闷指数之和的最小值。
样例输入 Copy
5
100 300 200 100 300
样例输出 Copy
400
 

#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
typedef  long long ll;
using namespace std;
#define rep(i,j,n) for(ll i=j;i<=n;i++)
#define per(i,j,n) for(ll i=j;i>=n;i--)
#define pr(x) printf("%lld\n",x) 
typedef unsigned long long ull;
typedef unsigned int us;
const ll INF=1e18+7;const double eps=1e-8,pi=acos(-1);
const ll mod=1e9+7;
const ll maxx=1e4+500;
inline bool read(ll &num){char in;bool IsN=false;in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
ll n,m,k;
ll fic[maxx];
ll qpow(ll a,ll b){	ll ans=1;	while(b)	{		if(b&1) ans=ans*a%mod;		b>>=1;		a=a*a%mod;	} return ans;}
ll cnm(ll n,ll m){	ll ans=fic[m]*fic[n-m]%mod;	return fic[n]*qpow(ans,mod-2)%mod;}
ll a[maxx];
ll sum[maxx];// 前缀和 
int main()
{
	cin>>n;
	rep(i,1,n)
	read(a[i]);
	sort(a+1,a+1+n);
	rep(i,1,n)
	{
		sum[i]=sum[i-1]+a[i];
	}	
	ll ans=INF;
	rep(i,1,n)
	{
		ll sum1=sum[i]; // 左边的和 
		ll sum2=sum[n]-sum[i]; // you1
		ll len1=i; // 长度 
		ll len2=n-i;
		ans=min(ans,len1*a[i]-sum1+sum2-len2*a[i]);
	}
	pr(ans);
	
	return 0;
}

G: 垒城堡

思路:最大的和是100*100=1e4,我们把所有可能的方案存下来,遇到一个新的就更新所有的方案,用vis[i]=1代表i可以被组合

XJR从小就喜欢用积木搭建各种各样的模型,虽然现在上六年级了,学习任务重了很多,但他学习之余,有空还忘不了拿出他那些积木进行一些富有创意的实验。一天,他拿出了一盒积木,碰巧发现这个盒子里装的所有积木都是棱长不等的正方体,他突发奇想,我拿这些积木来垒一个城堡,这个城堡可能达到多大的高度呢?XJR数学很好,他知道这些积木可以实现多种不同的高度,已知这些积木的棱长,他从数学角度推算出可能能够获得多少种不同的高度,但比较复杂。会编程的你,用程序来实现应该不是一件难事,你能帮助XJR用程序来实现吗?
已知积木的个数和每一个积木的棱长,你至少从中选择一个积木垒建城堡,请你编程求出城堡可以达到多少种不同的高度。

 

输入

共有两行:
第一行:是一个整数N(N<=100),表示一共有N个积木;
第二行:是N个正整数,两数之间用一个空格分隔,分别表示N个积木的棱长,每个积木的棱长不超过100。积木按照从大到小的尺寸给出。

输出

只有一个整数,表示城堡可能达到的多少种不同高度。

样例输入 Copy

3
3 2 1

样例输出 Copy

6
#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
typedef  long long ll;
using namespace std;
#define rep(i,j,n) for(ll i=j;i<=n;i++)
#define per(i,j,n) for(ll i=j;i>=n;i--)
#define pr(x) printf("%lld\n",x) 
typedef unsigned long long ull;
typedef unsigned int us;
const ll INF=1e18+7;const double eps=1e-8,pi=acos(-1);
const ll mod=1e9+7;
const ll maxx=1e4+500;
inline bool read(ll &num){char in;bool IsN=false;in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
ll n,m,k;
ll fic[maxx];
ll qpow(ll a,ll b){	ll ans=1;	while(b)	{		if(b&1) ans=ans*a%mod;		b>>=1;		a=a*a%mod;	} return ans;}
ll cnm(ll n,ll m){	ll ans=fic[m]*fic[n-m]%mod;	return fic[n]*qpow(ans,mod-2)%mod;}
ll vis[12000]; 
ll a[120];
int main()
{
	cin>>n;
	ll num=0,ans=0;
	rep(i,1,n)
	{
		read(a[i]);
		num+=a[i];
	}
	vis[0]=1;
	rep(i,1,n)
	{
		per(j,num,0) // 注意这样要从最大往小走, 避免计算重复,
		{
			if(vis[j]==1)
				vis[j+a[i]]=1;
		}
	}
	rep(i,1,num)
	if(vis[i]) ans++;
	pr(ans);
	return 0;
}

问题 I: 立方和 (就模拟一下~)  

#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
typedef  long long ll;
using namespace std;
#define rep(i,j,n) for(ll i=j;i<=n;i++)
#define per(i,j,n) for(ll i=j;i>=n;i--)
#define pr(x) printf("%lld\n",x) 
typedef unsigned long long ull;
typedef unsigned int us;
const ll INF=1e18+7;const double eps=1e-8,pi=acos(-1);
const ll mod=1e9+7;
const ll maxx=1e4+500;
inline bool read(ll &num){char in;bool IsN=false;in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
ll n,m,k;
ll fic[maxx];
ll qpow(ll a,ll b){	ll ans=1;	while(b)	{		if(b&1) ans=ans*a%mod;		b>>=1;		a=a*a%mod;	} return ans;}
ll cnm(ll n,ll m){	ll ans=fic[m]*fic[n-m]%mod;	return fic[n]*qpow(ans,mod-2)%mod;}
ll vis[12000]; 
ll f(ll a) 
{
	return a*a*a;	
} 
int main()
{
	cin>>n;
	ll ans;
	ll a1,a2,a3;
	ll cishu=0;
	while(1)
	{
		while(n>=1000) n-=1000;
		a1=n/100;
		a2=n/10-a1*10;
		a3=n%10;
		ans=f(a1)+f(a2)+f(a3);
		
		if(ans==n)
		{
			pr(ans);
			return 0;
		}
		n=ans;
		cishu++;
		if(cishu>=1000) break;
	}
	printf("error\n");
	return 0;
}

 J: 智力大奖赛

找个规律,两分钟完事

//1 3 5 7....
//3 6 9 12....
	cin>>n;
	pr(n*(1+2*n-1)/2);
	pr(n*(3+3*n)/2);

K: 求素数I() 把数找出来去重复判断一下素数就完事了,懒得写了

现给你N个0~9的数字并排成了一列,同时还给出了一个取数长度L。规定先从第1个数字开始从左往右连续取L个数字,拼成一个长度为L位(最高位为0的L-1位数除外)的数,然后从第2个数字开始从左往右连续取L个数字……,这样,最后最多可以得到N-L+1个L位数。现在请你将这些L位数中的素数按从小到大的顺序输出(如果产生重复,只需输出一个)。

输入

输入共有两行。
第一行为N和L,中间用空格隔开。(1≤N≤100,1≤L≤7)第二行为N个0~9的数字,中间用空格隔开。

输出

输出只有一行,含全部满足条件的素数,中间用逗号隔开。

样例输入 Copy

10 3
8 9 1 0 2 3 5 4 7 6

样例输出 Copy

547
  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值