题意:
A(CodeForces - 1251E1&E2):有n个人,每个人有各自的mi 和 pi。 如果有mi个人投你,那么他也会投你,如果不是mi个人投你,若让他投你,你就得花费pi 去贿赂他,问所有人投你要花费多少。
B(CodeForces - 1251C):一个数字字符串,如果相邻的两个数奇偶性不同则可以交换,问你这个数字最后最小是多少,保留零。
C(CodeForces - 1251A):键盘坏了,按某个键会自动多按一次,找一定好的键。
D(CodeForces - 1251D):N个员工,一共有K元钱,每个员工工资有范围,问怎么分配才能让工资中位数最大。
E(CodeForces - 1251F):给你一堆木条,一些是白色的,一些是红色的。然后要把这些木条拼到一起构成长度先递增后递减的样子,然后要求红色木条长度最长,问最后使得这个拼凑出来的多边形的周长为Qi的方案数是多少。
F(CodeForces - 1251B):n串01字符串,问你经过任意交换后,最后能得到多少个回文串。
补题:
A codeforces1251E1 Voting
思路:向后枚举,从n到1进行选择。如果当前人数有i个的话,就可以全投了,pi的处理其实就好的多了,我们可以用贪心的办法解决,如果说 N - size < i,那么,我们的size一定是偏大了,我们就可以去把偏大的部分给买通了,这时候就可以用优先队列去找这size里面的最小p值即可。
代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
const int maxN = 2e5 + 7;
int N;
vector<int> vt[maxn];
using namespace std;
int main()
{
int T,m,p;
cin>>T;
while(T--)
{
scanf("%d", &N);
for(int i=0; i<=N; i++) vt[i].clear();
for(int i=1; i<=N; i++) { scanf("%d%d", &m, &p); vt[m].push_back(p); }
priority_queue<int, vector<int>, greater<int>> Q;
ll ans = 0;
for(int i=N; i>=0; i--)
{
int len = (int)vt[i].size();
for(int j=0; j<len; j++) Q.push(vt[i][j]);
while(Q.size() > N - i) { ans += Q.top(); Q.pop(); }
}
printf("%lld\n", ans);
}
return 0;
}
B CodeForces - 1251C Minimize The Integer
思路:数组分成奇数和偶数两组,两组相对位置不变。每次输出两个数组中的小数。
代码:
#include<bits/stdc++.h>
using namespace std;
int t,l;
char x[300010],y[300010];
string a;
int main()//相对位置不变
{
cin>>t;
while(t--){
cin>>a;
l=a.size();
int i=0, j=0,l1=0,l2=0;
for(i=0;i<l;i++){
if((a[i]-'0')%2==1)
x[l1++]=a[i];
else
y[l2++]=a[i];
}
i=0;
j=0;
while(i < l1 || j < l2)
{
if(i >= l1)
cout<<y[j++];
else if(j >= l2)
cout<<x[i++];
else if(x[i] <= y[j])
cout<<x[i++];
else
cout<<y[j++];
}
cout<<endl;
}
}
C CodeForces - 1251A Broken Keyboard
思路:出现重复的数直接跳过,单个出现的数,统计数组自加。
代码:
#include<bits/stdc++.h>
using namespace std;
int t,l;
string s;
int main()
{
cin>>t;
while(t--){
cin>>s;
l=s.size();
int a[27]={0};
for(int i=0;i<l;i++){
if(s[i]==s[i+1])
i++;
else
a[s[i]-'a'+1]++;
}
for(int i=1;i<27;i++)
if(a[i]>0)
cout<<char(i+'a'-1);
cout<<endl;
}
}
D CodeForces - 1251D Salary Changing
思路:用pair数组存储每个员工的最小和最大工资,然后进行降序排序。记过程中工资中位数为mid,我们选定一个区间二分查找这个mid;如果所有员工都发放最小工资,那么此刻的mid就应该是所有mid的下界,而总工资S则应该是mid的上界。每次选定一个mid后,我们应该判断这个mid合不合适,判断条件是能找到(n+1)/2个人的工资可以达到mid且总工资不会超过S,排序+贪心选取这个(n+1)/2个人。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> P;
#define fi first
#define sc second
#define rp(i,n) for(int i=0;i<n;i++)
#define rpn(i,n) for(int i=1;i<=n;i++)
const int MAX_N=2e5+5;
P emp[MAX_N];
int n,num;
LL s;
bool ok(LL mid){
LL cost=0;
int ans=0;
rp(i,n){
if(emp[i].fi>=mid) ans++;
else if(emp[i].sc>=mid){
cost+=mid-emp[i].fi;
ans++;
}
if(cost>s) return false;
if(ans==num) return true;
}
return false;
}
int main(){
IOS;
int t;
cin>>t;
while(t--){
cin>>n>>s;
num=(n+1)>>1;
rp(i,n) cin>>emp[i].fi>>emp[i].sc;
sort(emp,emp+n,greater<P>());
LL lf=emp[n>>1].fi,rt=s,rs;
rp(i,n) s-=emp[i].fi;
while(rt>=lf){
LL mid=(lf+rt)>>1;
if(ok(mid)){
lf=mid+1;
rs=mid;
}
else rt=mid-1;
}
cout<<rs<<'\n';
}
return 0;
}
F CodeForces - 1251B Binary Palindromes(贪心)
思路:首先奇数不用管,已有的奇数也全部变成偶数。统计0和1的数目,每次只要放偶数个0和偶数个1就一定行。将0和1都变成偶数(奇数减1)之后,实际上二者等价,合并起来。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 7;
char s[55];
int main() {
int T;scanf("%d",&T);
while(T--) {
int n;scanf("%d",&n);
vector<int>now;
int one = 0,zero = 0;
for(int i = 1;i <= n;i++) {
scanf("%s",s + 1);
int len = strlen(s + 1);
now.push_back(len / 2 * 2);
for(int j = 1;j <= len;j++) {
if(s[j] == '1') {
one++;
} else {
zero++;
}
}
}
zero = zero / 2 * 2;
one = one / 2 * 2;
sort(now.begin(),now.end());
int ans = n;
for(int i = 0;i < now.size();i++) {
if(zero >= now[i]) {
zero -= now[i];
}
else if(one >= now[i]) {
one -= now[i];
}
else if(zero + one >= now[i]){
if(zero >= one) {
zero -= now[i] - one;
one = 0;
}
else {
one -= now[i] - zero;
zero = 0;
}
}
else {
ans--;
}
}
printf("%d\n",ans);
}
return 0;
}
感想:B题以前弄VB的时候好像见过,但一开始还是想直接冒泡上去,WA之后重新考虑了奇偶数之间的关系。C题再调的时候一开始是用continue,但案例都不行,换成i++就行了,就挺烦的。感觉状态有点崩,明天打完之后要好好调一下了。