目录
A-完美序列
解题思路
所谓完美序列,就是让我们找给定的序列a中,选任意元素任意排列顺序,能组成最长的一个满足
的序列的长度。那么我们可以用哈希表mp记录每个数字的个数,然后遍历可能的和的值2~10000,第二层循环从1 ~i/2,为了缩短时间同时防止重复记录,然后再令y=i-j,看满足这个条件的数有多少个,如果他的值和j相等,组合对数就加mp[j]/2,否则就取二者个数的最小值,最后更新一下最大值ans。输出即可。
AC代码
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define int long long
#define PII pair<int,int>
#define fi first
#define se second
#define endl '\n'
const int N=2e5+5;
const int inf=5000;
int n,num,mp[inf+10];
void solve()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>num,mp[num]++;
int ans=0;
for(int i=2;i<=10000;i++)
{
int res=0;
for(int j=1;j<=i/2;j++)
{
int x=i-j;
if(x>inf)continue;
if(x==j)
res+=mp[x]/2;
else
res+=min(mp[x],mp[j]);
}
ans=max(res,ans);
}
cout<<ans*2;
}
signed main()
{
IOS;
int _=1;
// cin>>_;
while(_--)
solve();
return 0;
}
C-合并石子
解题思路
这道题我是分别记录位置i的左边所有数到达它需要的步数和右边所有数需要到达他的总步数,最后再将二者相加就是所有石子需要到达他的总步数。通过前缀和记录每个位置需要移动的石子个数,(数字+k-1)/k是向上取整的意思,再将每个位置的步数累加。然后遍历筛选一个最小的总和,ans初始值不能赋INT_MAX,不然会wa一半。。。因为题目中数字较大,所以初值赋1e18.
AC代码
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define int long long
#define PII pair<int,int>
#define fi first
#define se second
#define endl '\n'
const int N=1e6+6;
int n,k,a[N],b[N],c[N],s1[N],s2[N],l[N],r[N];
void