CF574A优先队列是一个数加上另外一些数,使这个数在这些数中最大

本文详细解析了一个让人脑抽的优先队列应用问题,通过实例演示了如何利用优先队列解决此类问题,从最大值减一、排序循环入手,最终给出了一段高效且简洁的代码实现,旨在帮助读者理解和掌握优先队列的应用技巧。

这题大水题一个,至于我,一定是脑抽了WA到最后,想想都觉得呵呵。

其实就是每次让最大的数减一,然后排次序,如此循环即可。

另外也可以用优先队列来做,

这里贴上优先队列的代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<cctype>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<ctime>
#include<algorithm>
#define LL long long
using namespace std;
priority_queue<int> q;
int main()
{
    int n;
    while(cin>>n)
    {
        int best;
        cin>>best;
        for(int i=1;i<n;i++)
        {
            int in;
            cin>>in;
            q.push(in);
        }
        int ans=0;
        while(q.top()>=best)
        {
            ans++;
            int v=q.top()-1;
            q.pop();
            q.push(v);
            best++;
        }
        cout<<ans<<endl;
    }
    return 0;
}


#include <bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i,s,t) for(register ll i = s;i <= t;++i) #define per(i,t,s) for(register ll i = t;i >= s;--i) const ll N = 1e5 + 5; ll n; bool flag; ll num[N] = {}; ll cnt[N] = {}; string s = ""; deque <ll> q1; deque <ll> q2; inline ll read() { ll x = 0; ll y = 1; char c = getchar(); while(c < &#39;0&#39; || c > &#39;9&#39;) { if(c == &#39;-&#39;) y = -y; c = getchar(); } while(c >= &#39;0&#39; && c <= &#39;9&#39;) { x = (x << 3) + (x << 1) + (c ^ &#39;0&#39;); c = getchar(); } return x * y; } inline void write(ll x) { if(x < 0) { putchar(&#39;-&#39;); write(-x); return; } if(x > 9) write(x / 10); putchar(x % 10 + &#39;0&#39;); } int main() { cin >> s; n = s.size(); s = " " + s; rep(i,1,n) cnt[s[i] - &#39;0&#39;]++; rep(i,0,9) num[i] = cnt[i]; rep(i,1,9) { if(cnt[i] > cnt[9 - i] && num[10 - i] > num[i - 1]) { q1.push_front(i); q2.push_front(10 - i); cnt[i]--; num[10 - i]--; flag = true; break; } } if(!flag) { rep(i,1,9) { if(cnt[i] && num[10 - i]) { q1.push_front(i); q2.push_front(10 - i); cnt[i]--; num[10 - i]--; break; } } } rep(i,0,9) { rep(j,1,min(cnt[i],num[9 - i])) { q1.push_front(i); q2.push_front(9 - i); } cnt[i] -= min(cnt[i],num[9 - i]); num[9 - i] -= min(cnt[i],num[9 - i]); } while(cnt[0] && num[0]) { q1.push_back(0); q2.push_back(0); cnt[0]--; num[0]--; } rep(i,0,9) rep(j,1,cnt[i]) q1.push_front(i); rep(i,1,9) rep(j,1,num[i]) q2.push_front(i); while(!q1.empty()) { write(q1.front()); q1.pop_front(); } putchar(&#39;\n&#39;); while(!q2.empty()) { write(q2.front()); q2.pop_front(); } return 0; } #include<bits/stdc++.h> #define int long long using namespace std; const int N=1e3+5; int read() { int ret=0,f=1;char c=getchar(); while(!(c>=&#39;0&#39;&&c<=&#39;9&#39;)) { if(c==&#39;-&#39;) f=-1; c=getchar(); } while(c>=&#39;0&#39;&&c<=&#39;9&#39;) { ret=ret*10+c-&#39;0&#39;; c=getchar(); } return ret*f; } string s; int len,cnt[N],p[N]; deque<int> d1,d2; void solve() { cin>>s;len=s.size(); for(int i=0;i<len;i++) cnt[s[i]-&#39;0&#39;]++; for(int i=0;i<=9;i++) p[i]=cnt[i]; int flag=0; for(int i=1;i<=9;i++) { if(cnt[i]>cnt[9-i]&&p[10-i]>p[9-(10-i)]) { d1.push_front(i);d2.push_front(10-i); cnt[i]--;p[10-i]--;flag=1;break; } } if(!flag) { for(int i=1;i<=9;i++) { if(cnt[i]&&p[10-i]) { if(cnt[i]&&p[10-i]) { d1.push_front(i);d2.push_front(10-i); cnt[i]--;p[10-i]--;break; } } } } for(int i=0;i<=9;i++) { for(int j=1;j<=min(cnt[i],p[9-i]);j++) { d1.push_front(i); d2.push_front(9-i); } int k=min(cnt[i],p[9-i]); cnt[i]-=k,p[9-i]-=k; } while(cnt[0]&&p[0]) { d1.push_back(0),d2.push_back(0); cnt[0]--,p[0]--; } for(int i=0;i<=9;i++) { for(int j=1;j<=cnt[i];j++) { d1.push_front(i); } } for(int i=1;i<=9;i++) { for(int j=1;j<=p[i];j++) { d2.push_front(i); } } while(d1.size()) { cout<<d1.front();d1.pop_front(); } cout<<endl; while(d2.size()) { cout<<d2.front();d2.pop_front(); } } signed main() { solve(); return 0; } 为什么第二段代码AC,第一段代码WA? # CF138B Digits Permutations ## 题目描述 Andrey 最喜欢的字是 $n$。Andrey 的朋友们在新年送给了他两个相同的字 $n$。他把它们挂在墙上,满怀喜爱地注视着它们。 后来,Andrey 看腻了同样的字,于是他开始交换这两个数字中的字顺序,先在第一个字里换,再在第二个数字里换,然后又在第一个字里换,如此反复(每个数字可以进行任意次的交换)。某一时刻,他发现,如果将这两个经过重新排列的字相加,所得的和末尾的零的量在所有可能的排列中达到了最大。 给定字 $n$,你能找出满足上述条件的两个数字排列吗? ## 输入格式 第一行包含一个正整 $n$,即原始字。该字的位不超过 $10^{5}$。字没有前导零。 ## 输出格式 输出两行,每行一个 $n$ 的字排列,使得这两个数字相加所得的和末尾零的最大。排列可以有前导零(如果有的话,全部输出)。两个排列可以相同。如果有多组答案,输出任意一组即可。 ## 输入输出样例 #1 ### 输入 #1 ``` 198 ``` ### 输出 #1 ``` 981 819 ``` ## 输入输出样例 #2 ### 输入 #2 ``` 500 ``` ### 输出 #2 ``` 500 500 ``` ## 说明/提示 由 ChatGPT 4.1 翻译
10-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值