题目描述
链接:https://ac.nowcoder.com/acm/contest/11227/C
来源:牛客网
鸡尾酒的学生丹丹分不清求余和减法,因为他觉得两种运算都是将一个数字变小,所以都差不多。
为了让丹丹能够更好地理解求余和减法,鸡尾酒给了他这样一个问题:
给定 nn 个数字,每次有两种操作:
- 从所有正整数中任选一个数字 x(x >= 2)x(x>=2),并将所有数字全部对 xx 求余。
- 从这 nn 个数字中任选一些数字,使得它们全部减去一。
问最少进行多少次操作可以让所有数字全部变为 0。
这两种操作都需要“任选”,而丹丹有选择困难症,所以无法解决这一问题,你可以帮帮他吗?
题意
思路
- 意识到操作次数不会大于两次,因为可以把所有的奇数减一变为偶数,然后把所有偶数mod 2。
- 考虑小于2的情况:
- 全为0,不需要操作(因为没注意可以为0wa一次)
- 全为偶数,直接mod2
- 含奇数,全为1,直接全减一
- 含奇数,但不全为1,必须操作两次
- 含奇数,但没有1最小值,检验每个数是否为最小数的倍数
code
#include<bits/stdc++.h>
#define DEBUG(x) #x<<":"<<(x)<<' '
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
// const int mod=1e9+7;
const int N=1e5+10;
vector<int> vec;
void solv()
{
int n,t,ans=0;
int cntodd=0,cnteven=0,cnt1=0;
cin>>n;
int minn=0x3f3f3f3f;
for(int i=1;i<=n;i++)
{
cin>>t;
if(t)
{
vec.push_back(t);
if(t&1)cntodd++;
else cnteven++;
if(t==1)cnt1++;
minn=min(minn,t);
}
}
n=vec.size();
if(n==0)ans=0;
else if(cnteven==n)ans=1;
else
{
if(cnt1==n)ans=1;
else if(minn==1)ans=2;
else
{
ans=1;
for(int i=0;i<n;i++)
{
if(vec[i]%minn)
{
ans=2;
break;
}
}
}
}
cout<<ans<<'\n';
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int T=1;
// cin>>T;
while(T--)
{
solv();
}
return 0;
}
注意与总结
- 这里直接将所有0舍去,n中减去0的个数有助于简化后面的判断条件