B题如下:
AC代码如下:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
int s1[200005], s2[200005];
int main()
{
ios::sync_with_stdio(false);
int T;
cin >> T;
while (T--)
{
int n, x;
ll minn = INF;
int u;
memset(s1, 0, sizeof(s1));
memset(s2, 0, sizeof(s2));
cin >> n >>x ;
for (int i = 1; i <= n; i++)
{
cin >> s1[i];
int t = s1[i];
while (t % x == 0)
{
s2[i]++;
t = t / x;
}
if (s2[i] < minn)
{
minn = s2[i];
u = i;
}
}
ll sum = 0;
for (int i = 1; i <= n; i++)
{
if (i <u)
{
sum += s1[i] * (minn + 2);
}
else
{
sum += s1[i] * (minn+1);
}
}
cout << sum << endl;
}
return 0;
}
思路:根据题目要求如果 n 可以被x整除,就在数组的尾部添加 x 个 n/x。不难发现x个n/x的总和还是n,所以只用求出每个数最大能被x除以几次,再找到他们的次数的最小值就解决了。
C题如下:
AC代码如下:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=3e5+5;
void solve()
{
int n,m;
int s1[N],s2[N];
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>s1[i];
for(int i=1;i<=m;i++)cin>>s2[i];
sort(s1+1,s1+1+n);
ll sum=0;
int j=1;
for(int i=n;i>=1;i--)
{
if(s2[j]<s2[s1[i]])
sum+=s2[j++];
else sum+=s2[s1[i]];
}
cout<<sum<<endl;
}
int main()
{
ios::sync_with_stdio(false);
int T;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
思路:题目要求找所有的最小值,那么就可以用贪心的思想。先将s1排序,不难发现,s1种的最大值如果选最小的礼物则可以保证差值最大,以此类推,可以求出小的价值。
总结:
这次比赛又掉分了,关键还是B题出大问题,思路上我没问题,但被一个语法卡爆了。
即一开始我没有用ll定义minn。
ll minn = INF;
这样直接导致了下面的结果溢出。
sum += s1[i] * (minn + 2);
这是为什么呢?我不是已经用ll定义了sum吗?
举个例子:
double a=5/2;
大家可以看看输出的是多少。
所以 我虽然用ll 定义了sun ,但是 s1[i]*(minn+2) 还是int 类型,所以会爆炸。
C题是赛后补题,发现C题不难,所以这次掉分亏爆了!