牛客小白月赛31

这篇博客主要解析了两道编程竞赛题目。第一题是关于整数消减的问题,通过不断加和减找到能被目标整数整除的最小公倍数。第二题涉及数组排列计算,通过抵消特定数值确保计算结果在特定范围内。博主提供了详细的思路分析及C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

牛客小白月赛31

F、消减整数

原题链接
胡乱分析:
假设给定数字为 n n n,一直减,直到发现在减 k k k时,不够减,此时 n n n还剩下 m m m,根据题意,需要 m + n m+n m+n然后重新减,然后发现剩下 2 m 2m 2m,再加再减,发现剩下 3 m 3m 3m,直到剩下的 a m am am可以减去 k k k,减去后若不能完全减完,则又需要重复上述步骤,继续加继续减。
所以题目可以理解为要加几次 m m m,才能把 k k k完全消去,没有剩余。假设 2 m 2m 2m可以减去 k k k了,但还有剩余,就变成 2 m − k + m = 3 m − k 2m-k+m=3m-k 2mk+m=3mk,若还有剩余,则继续加 m m m,变成 4 m − k 4m-k 4mk,发现又可以减k了,变成 4 m − 2 k 4m-2k 4m2k,若还有剩余,则以此类推,直到发现 6 m − 3 k = = 0 6m-3k==0 6m3k==0了(假设)为止。
所以问题就演变成了:经过多少次 + m +m +m的操作后, a m am am可以整除 k k k,也就是经过多少次操作后, a m am am变成了 m m m k k k的最小公倍数。
代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n,k=1;;
		cin>>n;
		while(n-k>0)
		{
			n=n-k;
			k++;
		}
		if(n-k==0)
			cout<<"1"<<endl;
		else
			for(int a=2;;a++)
				if((a*n)%k==0)
				{
					cout<<a<<endl;
					break;
				}
		
	}
	return 0;
} 

J、排列算式

原题链接
胡乱分析:
根据题意,计算过程中数字不会超过 3 3 3也不会小于 0 0 0,输入保证每一个数字都是 − 3 , − 2 , − 1 , + 0 , + 1 , + 2 , + 3 −3, −2, −1, +0, +1, +2,+3 3,2,1,+0,+1,+2,+3的其中一个,稍加思考就会发现:
输入总和不能超过 3 3 3也不会小于 0 0 0
当输入的数组中出现 − 3 -3 3时,要将它抵消为 0 0 0,否则不能满足要求,因为 − 3 -3 3无论加减什么数字,都不符合要求。
当输入的数组中出现;俩个或以上的 3 3 3时,要将多余的 3 3 3抵消为 0 0 0,否则不能满足要求,因为在总和不能超过 3 3 3也不会小于 0 0 0的前提下,一个 3 3 3是不会不符合要求的。
所以问题就变成了抵消 3 3 3 − 3 -3 3的过程,若能抵消到符合上述要求,那么存在一种符合题意的计算顺序。
代码:

#include<bits/stdc++.h>
using namespace std;
int a[10];
bool judge() 
{
   while(a[0])
   {
   	if(a[6])   
   		a[6]--;     //+3
   	else if(a[4]>2) 
   		a[4]-=3;    //+1+1+1
   	else if(a[5]&&a[4])
   	{
   		a[5]--;
   		a[4]--;    //+2+1
   	}
   	else if(a[5]>1&&a[2])
   	{ 
   		a[5]-=2;
   		a[4]--;     //+2+2-1
   	}
   	else 
   		return false;
   	a[0]--;
   }
   while(a[6]>1)
   {
   	if(a[1]>1&&a[4])
   	{
   		a[1]-=2;
   		a[4]--;      //-2-2+1
   	}
   	else if(a[1]&&a[2])
   	{
   		a[1]--;
   		a[2]--;      //-2-1
   	}
   	else if(a[2]>2) 
   		a[2]-=3;     //-1-1-1
   	else 
   		return false;
   	a[6]--;
   }
   return true;
}

int main()
{
   int T;
   cin>>T;
   while(T--)
   {
   	memset(a,0,sizeof(a));
   	int n,sum=0,x;
   	cin>>n;
   	for(int i=0;i<n;i++)
   	{
   		cin>>x;
   		sum+=x;
   		a[x+3]++;
   	}
   	if(judge()&&sum>=0&&sum<=3)
   		cout<<"Yes"<<endl;
   	else
   		cout<<"No"<<endl;
   }
   return 0; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值