删数问题
今天学了学优先队列,做了做P1323删数问题,但首先调了调P1106删数问题的代码(前几天WA了)。
先看P1106:
洛谷P1106 删数问题
题目描述
键盘输入一个高精度的正整数 N(不超过 250 位),去掉其中任意 k 个数字后剩下的数字按原左右次序将组成一个新的非负整数。编程对给定的 N 和 k,寻找一种方案使得剩下的数字组成的新数最小。
输入格式
n(高精度的正整数 )。
k(需要删除的数字个数 )。
输出格式
最后剩下的最小数。
输入输出样例
int p=0; for(int i=1;i<=n;i++){ if(shu[i]!=-1&&(shu[i]!=0||p==1)){ p=1; cout<<shu[i]; } } if(p==0) cout<<0;
2.我删数的时候是将这位数改为-1,可是如果碰到-1,向前找的也会停止,那就要将-1无视掉,直接往前找,只有找到比它小的数才会停。
if(shu[i]>shu[i+1]){ shu[i]=-1; k--; int t=i; while(t>1&&shu[i+1]<shu[t-1]&&k>0){ shu[t-1]=-1; t--; k--; } }
下面是这道题完整的代码:
#include<iostream> #include<cstring> using namespace std; int main(){ char a[255]; scanf("%s",a); int n=strlen(a); int shu[255]; for(int i=1;i<=n;i++){ shu[i]=a[i-1]-'0'; } int k; cin>>k; for(int i=1;i<=n;i++){ if(k==0){ break; } if(shu[i]>shu[i+1]){ shu[i]=-1; k--; int t=i; while(t>1&&shu[i+1]<shu[t-1]&&k>0){ shu[t-1]=-1; t--; k--; } } } int p=0; for(int i=1;i<=n;i++){ if(shu[i]!=-1&&(shu[i]!=0||p==1)){ p=1; cout<<shu[i]; } } if(p==0) cout<<0; return 0; }
洛谷P1323 删数问题
题目描述
一个集合有如下元素:1 是集合元素;若 P 是集合的元素,则 2×P+1,4×P+5 也是集合的元素。
取出此集合中最小的 k 个元素,按从小到大的顺序组合成一个多位数,现要求从中删除 m 个数位上的数字,使得剩下的数字最大,编程输出删除前和删除后的多位数字。
注:不存在所有数被删除的情况。
输入格式
只有一行两个整数,分别代表 k 和 m。
输出格式
输出为两行两个整数,第一行为删除前的数字,第二行为删除后的数字。
输入输出样例
数据规模与约定
- 对于 30% 的数据,保证 1≤k,m≤300。
- 对于 100% 的数据,保证 1≤k,m≤3×10^4。
优先队列的部分很少,优先队列就是STL中的一个队列,默认为小跟堆,加进去后直接自动排列为小跟堆。
头文件:
#include<queue>
优先队列定义:
priority_queue<ll,vector<ll>,greater<ll> > ji;//ll为long long。
加入元素:
ji.push(i);
取出头元素:
i=ji.top();
删除头元素:
ji.pop();
然后说一下这道题的思路,这个集合就是{P,2*P+1,4*P+3,4*P+5,……}(P=1),其中P的系数是4n的数就是P的系数是2n的数*2+1和P的系数是n的数*4+5,以此类推,这样就是一个斐波那契数列,但是这样就有一个问题,优先队列中只能取到队列中最小的数,想要处理下一个数就需要将头元素删掉,那么我们就不能将P的系数为2n的数和为n的数运算得到P的系数是4n的数,而是要将P的系数为n的数处理成为P的系数为2n得数和为4n的数,并随着输出(我这里是先存下来——为删数而存,再在结束后输出)。
int x=0,y=1; while(k>0){ for(int i=1;i<=min(x,k);i++){ ll t=ji.top(); ji.pop(); ji.push(t*2+1); ji.push(t*4+5); int cnt=a[0]+1; while(t>0){ a[++a[0]]=t%10; t=t/10; } int j=a[0]; while(cnt<j){ swap(a[cnt],a[j]); cnt++; j--; } } k-=min(x,k); int t=x; x=y; y+=t; }
下面是整个的代码:
#include<iostream> #include<queue> #define ll long long using namespace std; priority_queue<ll,vector<ll>,greater<ll> > ji; int a[300010]; int main(){ int k,m; cin>>k>>m; ji.push(1); int x=0,y=1; while(k>0){ for(int i=1;i<=min(x,k);i++){ ll t=ji.top(); ji.pop(); ji.push(t*2+1); ji.push(t*4+5); int cnt=a[0]+1; while(t>0){ a[++a[0]]=t%10; t=t/10; } int j=a[0]; while(cnt<j){ swap(a[cnt],a[j]); cnt++; j--; } } k-=min(x,k); int t=x; x=y; y+=t; } for(int i=1;i<=a[0];i++){ cout<<a[i]; } cout<<endl; for(int i=1;i<=a[0];i++){ if(m==0){ break; } if(a[i]<a[i+1]){ a[i]=-1; m--; int t=i; while(t>1&&(a[i+1]>a[t-1]||a[t-1]==-1)&&m>0){ if(a[t-1]!=-1) m--; a[t-1]=-1; t--; } } } int p=0; for(int i=1;i<=a[0];i++){ if(a[i]!=-1&&(a[i]!=0||p==1)){ p=1; cout<<a[i]; } } if(p==0) cout<<0; return 0; }