codeforces Div.2 #429 B.Godsend C. Leha and Function

原题链接:B:Godsend

大意:
一串数列。A,B 轮流取一些数字。 A 先走,每次从中抽取和为奇数的串,(抽完后自动缩为一个新串)。B 每次从中取和为偶数的串。最后一个无法操作的人输。

思路:
博弈论水题。若和为奇数,那么 A 赢,若和为偶数, A 一开始若能从中抽走奇数,那么 B 输,否则 A 输。
比赛时hack看到的代码写法实在太多了。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mem(s,t) memset(s,t,sizeof(s))
//#define D(v) cout<<#v<<" "<<v<<endl
#define inf 0x3f3f3f3f
#define pb push_back
//#define LOCAL
inline void read(int &x){
    x=0;char p=getchar();
    while(!(p<='9'&&p>='0'))p=getchar();
    while(p<='9'&&p>='0')x*=10,x+=p-48,p=getchar();
}
int a[1000];
const int mod=1e9+7;
int main() {
    int ans=0,f=0;
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        int x;
        cin>>x;
        if(x&1) f=1;
        ans+=(x%2);
    }
    if(ans&1) puts("First");
    else if(ans%2==0 && f) puts("First");
    else puts("Second");
    return 0;
}

C.Leha and Function

大意:
题目包装得很多。对于一个数列, F(n,k) 表示数列中的第 {1,2,3,…n} 个数中选取 k 个数,k 个数中最小数的数学期望。
现在给出两个数列,A,B ,即为上述数列,B 为 k 的集合。
现在求 这里写图片描述最大。
看了一下样例是倒序匹配,实际上贪心地想想也是对的。
逆序和大于等于乱序和大于等于顺序和

写法一:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mem(s,t) memset(s,t,sizeof(s))
#define D(v) cout<<#v<<" "<<v<<endl
#define inf 0x3f3f3f3f
#define pb push_back
//#define LOCAL
inline void read(int &x){
    x=0;char p=getchar();
    while(!(p<='9'&&p>='0'))p=getchar();
    while(p<='9'&&p>='0')x*=10,x+=p-48,p=getchar();
}
int a[200005],b[200005],c[200005];
int main() {
    int m;
    read(m);
    for(int i=0;i<m;i++) read(a[i]);
    for(int i=0;i<m;i++){
        read(b[i]);
        c[i]=b[i];
    }
    sort(a,a+m,[&](int x,int y){return x>y;});
    sort(b,b+m);
    for(int i=0;i<m;i++) printf("%d%c",a[lower_bound(b,b+m,c[i])-b]," \n"[i==m-1]),b[lower_bound(b,b+m,c[i])-b]--;//找到位置,然后这个位置的bi--,防止影响下次查找
    return 0;
}

写法二:pair

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mem(s,t) memset(s,t,sizeof(s))
#define D(v) cout<<#v<<" "<<v<<endl
#define inf 0x3f3f3f3f
#define pb push_back
//#define LOCAL
inline void read(int &x){
    x=0;char p=getchar();
    while(!(p<='9'&&p>='0'))p=getchar();
    while(p<='9'&&p>='0')x*=10,x+=p-48,p=getchar();
}
int a[200005],b[200005],c[200005];
pair<int,int> ans[200005];
int main() {
    int m;
    read(m);
    mem(ans,0);
    for(int i=0;i<m;i++) read(a[i]);
    for(int i=0;i<m;i++){
        read(b[i]);
        ans[i]={b[i],i};
    }
    sort(a,a+m,greater<int>());
    sort(ans,ans+m);
    for(int i=0;i<m;i++){
        int to=ans[i].second;
        c[to]=a[i];
    }
    for(int i=0;i<m;i++) printf("%d%c",c[i]," \n"[i==m-1]);
    return 0;
}

顺便复习下pair,二维偏序,排序时先排一维,一维相同时再比较二维。

ps.最近学到了一些c++11的技巧,编译需要编译器支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值