A 题目链接 这里
题解:签到题,这个题和之前某一场的b描述是一样的,都是找不在当前数里的最小值,这个排个序,把相同的扔最后可以得到答案。
#include<bits/stdc++.h>
#define ll long long
#define pr pair<ll,ll>
#define ios ios::sync_with_stdio(false)
#define CRL(a) memset(a,0,sizeof a)
using namespace std;
const int maxn = 1e5 + 5;
int x[maxn];
int y[maxn];
int main()
{
ios;
int t;
cin >> t;
while(t--)
{
int n;
cin >> n;
for (int i = 1; i <= n;i++)
{
cin >> x[i];
}
sort(x + 1, x + 1 + n);
x[0] = -5;
int cnt = 0;
for (int i = 1; i <= n;i++)
{
if(x[i]!=x[i-1])
{
cout << x[i] << " ";
}
else
{
y[++cnt] = x[i];
}
}
for (int i = 1; i <= cnt;i++)
{
cout << y[i] << " ";
}
cout << endl;
}
}
B 题目链接 这里
题解:这个题目让我们找数组的划分,且数组里的每个数和他的下一个数相加都是一个数m的倍数,让我们求这样的划分最少有几个。我们可以桶排来找每个数有几个,但数据范围是1e9,我们需要进行取模,而且如果这个数本身就是m的倍数,我们可以把所有这样的数扔在一起形成一个划分。剩下的数我们可以找这个数与m的差,来确定这个划分中有几个数,这里有几个细节是需要注意下的,具体看代码。
#include<bits/stdc++.h>
#define ll long long
#define pr pair<ll,ll>
#define ios ios::sync_with_stdio(false)
#define CRL(a) memset(a,0,sizeof a)
using namespace std;
const int maxn = 1e5 + 5;
int x[maxn];
int y[maxn];
int main()
{
ios;
int t;
cin >> t;
while(t--)
{
int n, m;
cin >> n >> m;
memset(x, 0, sizeof x);
memset(y, 0, sizeof y);
int cnt = 0;
int ans = 0;
for (int i = 1; i <= n;i++)
{
int a;
cin >> a;
if(a%m)
x[++cnt] = a % m, y[a % m]++;
else
ans = 1;
}
for (int i = 1; i <= cnt;i++)
{
if(y[x[i]])
{
int b = m - x[i];
if(y[b])
{
if(y[x[i]]>y[b])
y[x[i]] = y[x[i]] - y[b] - 1, y[b] = 0;
else if(y[x[i]]==y[b])
y[x[i]] = 0, y[b] = 0;
else
y[b] = y[b] - y[x[i]] - 1, y[x[i]] = 0;
}
else
y[x[i]]--;
ans++;
}
}
cout << ans << endl;
}
}
C1题目链接 这里
题解:这个题说的是,让我们找3个数,使这三个数相加等于n,且这三个数的最小公倍数小于等于n/2. 既然要小于等于n/2,我们可以使这个数除以2,得到m,这样可以得到两个数,如果n-2m!=0,那么剩下的数就是第三个数,如果n-2m==0,那么我们就要考虑把这两个数分一点给第三个数,如果m是偶数,那么我们使m/2即可得到第三个数,如果m是奇数,那么除以二是不可以的,我们让每个数给第三个数1,这样第三个数为2,一定是m-1的因数,这时lcm也不会超过n/2.
#include<bits/stdc++.h>
#define ll long long
#define pr pair<ll,ll>
#define ios ios::sync_with_stdio(false)
#define CRL(a) memset(a,0,sizeof a)
using namespace std;
const int maxn = 5e6 + 5;
pr x[maxn];
int a[maxn], b[maxn];
int main()
{
int t;
cin >> t;
while(t--)
{
int n, m;
cin >> n >> m;
int b = n / 2;
int d = b;
int c = n - b * 2;
if(c==0)
{
if(b&1)
{
b--, d--;
c = 2;
}
else
d /= 2, c = d;
}
cout << b << " " << d << " " << c << endl;
}
return 0;
}
C2题目链接这里
题解:这个题和上个题不一样的是这次不是三个数了,而是任意数,但1对lcm是没有影响的,我们可以让第三个数后面的数全部为1,转化为上一题,求解。
#include<bits/stdc++.h>
#define ll long long
#define pr pair<ll,ll>
#define ios ios::sync_with_stdio(false)
#define CRL(a) memset(a,0,sizeof a)
using namespace std;
const int maxn = 5e6 + 5;
pr x[maxn];
int a[maxn], b[maxn];
int main()
{
int t;
cin >> t;
while(t--)
{
int n, m;
cin >> n >> m;
n -= m - 3;
int b = n / 2;
int d = b;
int c = n - b * 2 ;
if(c==0)
{
if(b&1)
{
b--, d--;
c = 2;
}
else
d /= 2, c = d;
}
cout << b << " " << d << " " << c << " ";
for (int i = 1; i <= m - 3;i++)
cout << 1 << " ";
cout << endl;
}
return 0;
}
E1题目链接 这里
题解:这个题让我们求子数组,每个数组当中的数相乘都不是完全平方数,让我们求这样的有几个。
由质因数分解我们可以知道任意一个大于1的正整数都能唯一分解为有限个质数的乘积。那么我们可以知道如果一个数和另外一个数相乘想成为平方数,他们相乘的数分解为质数的乘积,这些质数的次方都是2的倍数。我们可以让分解的质数的次方对2取余,然后让取余为1的质数相乘,可以得到这样的话必须两个数相等才能为完全平方数。然后我们就可以得到答案。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e7 + 5;
int pr[maxn], st[maxn];
int cnt = 0;
void prime(int n)
{
for (int i = 2; i <= n;i++)
{
if(st[i]==0)
{
st[i] = i;
pr[++cnt] = i;
}
for (int j = 1; j <= cnt;j++)
{
if(pr[j]>st[i]||pr[j]>n/i)
break;
st[i * pr[j]] = pr[j];
}
}
}
int main()
{
int t;
cin >> t;
prime(10000001);
while(t--)
{
int n, m;
cin >> n >> m;
vector<int> q(n, 1);
for (int i = 0; i < n;i++)
{
int a;
cin >> a;
int last = 0, ans = 0;
while(a>1)
{
int p = st[a];
if (p == last)
{
ans++;
}
else
{
if(ans%2)
q[i] *= last;
last = p;
ans = 1;
}
a /= p;
}
if(ans%2)
q[i] *= last;
}
int l = 0, ans = 1;
map<int, int> ma;
for (int i = 0; i < n;i++)
{
if(ma.find(q[i])!=ma.end()&&ma[q[i]]>=l)
{
ans++;
l = i;
}
ma[q[i]] = i;
}
cout << ans << endl;
}
}