Codeforces Round 916 (Div. 3)
A - Problemsolving Log
思路:
整体来看就是A需要出现一次,B需要出现两次依次类推
不要超过游戏时间
完整代码:
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>using namespace std;typedef long long ll;const int N=1e5+10;void solve()
{int n;cin>>n;string s;cin>>s;int cnt=0;map<char ,int>a;for(auto i:s){a[i]++;}for(auto i:a){if(i.second>=i.first-'A'+1&&i.second<=n){cnt++;n-=i.second;}}cout<<cnt<<endl;
}int main ()
{ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int t=1;cin>>t;while(t--)solve();return 0;
}
B - Preparing for the Contest
思路:
从第二个开始,后面要有K-1个比它大的数,所以前面K个数顺序输出,从第K个数过后,逆序输出答案。第二个到第K个满足K-1,后面逆序输出稳定一个数满足。
完整代码:
#include <iostream>
#include <algorithm>
#include <vector>using namespace std;typedef long long ll;const int N=1e5+10;void solve()
{int n,k;cin>>n>>k;for(int i=1;i<=k;i++)cout<<i<<" ";for(int i=n;i>k;i--)cout<<i<<" ";cout<<endl;
}int main ()
{ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int t=1;cin>>t;while(t--)solve();return 0;
}
C - Quests
思路:
贪心的选择第一轮完成,再重复选择经验最大的。
完整代码:
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;typedef long long ll;void solve() {int n, k;cin >> n >> k;vector<int> a(n), b(n);for (int i = 0; i < n; i++) cin >> a[i];for (int i = 0; i < n; i++) cin >> b[i];int sum = 0, max_b = 0, ans = 0;for (int i = 0; i < min(n, k); i++) {sum += a[i];max_b = max(max_b, b[i]);int cnt = k - (i + 1);ans = max(ans, sum + cnt * max_b);}cout << ans << endl;
}int main() {ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int t;cin >> t;while (t--) {solve();}return 0;
}
D - Three Activities
思路:
比较简单的DP,三种活动每种活动选人数最多的,每种不要冲突。
这里需要注意,如果不排序就要每一种活动都要循环一遍就是O(n3)O(n^3)O(n3),包超时的,排序只需要看前面三种,因为只有三种活动,能确保一定不会冲突,排序也需要注意序号,没有需要无法判断是否冲突
完整代码:
#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>using namespace std;typedef long long ll;void solve() {int n;cin >> n;vector<ll> a(n), b(n), c(n);for (int i = 0; i < n; i++) cin >> a[i];for (int i = 0; i < n; i++) cin >> b[i];for (int i = 0; i < n; i++) cin >> c[i];vector<pair<ll, int>> days_a, days_b, days_c;for (int i = 0; i < n; i++) {days_a.push_back({a[i], i});days_b.push_back({b[i], i});days_c.push_back({c[i], i});}sort(days_a.begin(), days_a.end(), greater<pair<ll, int>>());sort(days_b.begin(), days_b.end(), greater<pair<ll, int>>());sort(days_c.begin(), days_c.end(), greater<pair<ll, int>>());ll ans = 0;for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) for (int k = 0; k < 3; k++) if (days_a[i].second != days_b[j].second && days_a[i].second != days_c[k].second && days_b[j].second != days_c[k].second) ans = max(ans, days_a[i].first + days_b[j].first + days_c[k].first);cout << ans << endl;
}int main() {ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int t;cin >> t;while (t--) {solve();}return 0;
}
E - Game with Marbles (Easy Version)
思路:
一个博弈论,a最优策略是让自己的弹珠留得更多,b的最优也是让自己弹珠留的更多,从a的视角来看,要尽可能的让弹珠比自己多的b给全部扔掉,b同理。在这个简单的版本下应该是能过。时间复杂度大概在O(n2)O(n^2)O(n2)
优化版本:
上述思路不变,主要去优化对应ab的大小。
我们可以发现,我们不会太在意当前次序下ab谁大,我们的得分只从谁动手这里加减,比如,a动手,b一定为0,a做的贡献就是A-1。所以我们在意次序和AB的总和,以及动手顺序。
完整代码:
暴力版本:
#include <iostream>
#include <vector>using namespace std;typedef long long ll;void solve()
{int n;cin >> n;vector<ll> a(n), b(n);for (int i = 0; i < n; i++) cin >> a[i];for(int i=0;i<n;i++)cin>>b[i];bool moved = true;while (moved) {moved = false;int best = -1;for (int i = 0; i < n; i++) {if (a[i] > 0 && b[i] > 0) {if (best == -1 || (a[i] + b[i] > a[best] + b[best])) {best = i;}}}if (best != -1) {a[best]--;b[best] = 0;moved = true;}best = -1;for (int i = 0; i < n; i++) {if (a[i] > 0 && b[i] > 0) {if (best == -1 || (a[i] + b[i] > a[best] + b[best])) {best = i;}}}if (best != -1) {b[best]--;a[best] = 0;moved = true;}}ll sum = 0;for (int i = 0; i < n; i++) {sum += a[i] - b[i];}cout << sum << endl;
}int main() {int t;cin>>t;while(t--)solve();return 0;
}
优化版本:
#include <iostream>
#include <algorithm>
#include <vector>using namespace std;typedef long long ll;const int N=1e5+10;void solve()
{int n;cin>>n;vector<int>a(n),b(n);for(int i=0;i<n;i++)cin>>a[i];for(int i=0;i<n;i++)cin>>b[i];vector<pair<int,int>>sum;for(int i=0;i<n;i++){sum.push_back({a[i]+b[i],i});}sort(sum.begin(),sum.end(),greater<pair<int,int>>());ll ans=0;for(int i=0;i<n;i++){int y=sum[i].second;if(i%2==0)ans+=a[y]-1;elseans-=b[y]-1;}cout<<ans<<endl;}//(A-B)a希望大,b希望小
//a希望A剩得多,让B多的全部扔掉
//b希望B剩得多,让A多的全部扔掉
//A-1-(B-1)int main ()
{ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int t=1;cin>>t;while(t--)solve();return 0;
}
F - Game with Marbles (Hard Version)
思路:
这是个困难的版本,难点在于不能像简单版本一样模拟
好在我们优化了,优化了能过这个题。
