牛客小白月赛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
2m−k+m=3m−k,若还有剩余,则继续加
m
m
m,变成
4
m
−
k
4m-k
4m−k,发现又可以减k了,变成
4
m
−
2
k
4m-2k
4m−2k,若还有剩余,则以此类推,直到发现
6
m
−
3
k
=
=
0
6m-3k==0
6m−3k==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;
}