序列处理
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
int n;
cin>>n;
const int N=3010;
int a[N];
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+1+n);
int ans=0;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(a[i]==a[j]){
a[j]++;
ans++;
}
}
}
cout<<ans;
return 0;
}
数字重构 数字重构
思考 本题看到正确作答率很低后,我也就没有仔细思考,其实思路并不难想。 反思一下,如果拿到一个没法一眼看出来怎么做的题目,应该如何思考。首先看看是否可以直接模拟出来,注意观察数据量,模拟很可能超时。下图是我在网上找到的一幅蓝桥杯考点图,出处。然后考虑是否可以使用递归、dp、搜索,如果都很困难,可以思考二分答案是否能做。本题就是将第一个数进行排列组合,很容易想到全排列,也就是使用dfs求解。
这思路很好想,接下来的代码也很好写,我的这个代码应该是对的,不过超时了,超时的点结果也是对的。
代码1
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=20;
long long a,b;
int d[N];
int judge[N];
int n=1;
long long ans=0;
void dfs(long long sum,int x){
if(x==n+1){
if(sum<=b){
ans=max(sum,ans);
}
return ;
}
for(int i=1;i<=n;i++){
if(judge[i]==0){
judge[i]=1;
dfs(sum+d[i]*pow(10,x-1),x+1);
judge[i]=0;
}
}
}
int main(){
cin>>a>>b;
while(a!=0){
d[n]=a%10;
a/=10;
n++;
}
n--;
for(int i=1;i<=n;i++){
dfs(0,1);
}
cout<<ans;
return 0;
}
超时情况:
然后我想着优化,突然发现,这个难道不能直接从大到小全排列吗,如果遇到满足要求的直接 **exit(0) 退出程序** 在写代码的时候我发现降序的全排列并不能用原来的sum完成,具体原因难以打字描述,自己实验一下吧。 于是我换成了存进数组的方法。不过还是超时了,但是时间上提高了5倍多。
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=20;
long long a,b;
int d[N];
int judge[N];
int n=1;
long long ans=0;
int m[N];
bool cmp(int x,int y){
return x>y;
}
void dfs(int m[],int x){
if(x==n+1){
long long sum=0;
for(int i=1;i<=n;i++){
sum+=m[i]*pow(10,n-i);
}
if(sum<=b){
cout<<sum;
exit(0);
}
return ;
}
for(int i=1;i<=n;i++){
if(judge[i]==0){
judge[i]=1;
m[x]=d[i];
dfs(m,x+1);
judge[i]=0;
}
}
}
int main(){
cin>>a>>b;
while(a!=0){
d[n]=a%10;
a/=10;
n++;
}
n--;
sort(d+1,d+1+n,cmp);
for(int i=1;i<=n;i++){
dfs(m,1);
}
cout<<ans;
return 0;
}
看了题解后的做法 此做法使用了字符串,避免了用pow求值的麻烦
思路是贪心,看某一位能放的最大的数是几 详细讲解在代码中体现
这里是几个重要的代码模板 对字符串降序排列sort(a.begin(),a.end(),greater<char>()) 上面那个括号别忘了 遍历元素类型特殊的 for(auto c:a) 转化为string类型的 string res =to_string(x);
代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int cnt[10];
string get_min(int x){
string res =to_string(x);
cnt[x]--;
for(int i=0;i<10;i++)
for(int j=0;j<cnt[i];j++)
res+=to_string(i);
cnt[x]++;
return res;
}
int main(){
string a,b;
cin>>a>>b;
if(a.size()<b.size()){
sort(a.begin(),a.end(),greater<char>());
cout<<a<<endl;
}
else{
for(auto c:a) cnt[c-'0']++;
string res;
for(int i=0;i<a.size();i++)
for(int j=9;j>=0;j--)
if(cnt[j]&&res+get_min(j)<=b){
res+=to_string(j);
cnt[j]--;
break;
}
cout<<res<<endl;
}
return 0;
}
|