CF978

A. Bus to Pénjamo(模拟)

题意:大巴有r排,每排2个座位,另一个家庭成员与他们坐在同一排或独自坐一排则幸福,最多有多少人感到幸福

代码:

#include<bits/stdc++.h>
using namespace std;
int a[510];
int main(){
    int t;cin>>t;
    while(t--){
        int n,r;cin>>n>>r;
        for(int i=1;i<=n;i++)cin>>a[i];
        int ans=0,cnt=0;
        //cout<<"**********\n";
        for(int i=1;i<=n;i++){
            //cout<<"&\n";
            if(a[i]%2==0){
                ans+=a[i];
                r-=(a[i]/2);
            }
            else{
                ans+=(a[i]-1);
                r-=(a[i]/2);
                cnt++;
            }
        }
        if(cnt<r){
            ans+=cnt;
        }else{
            ans+=(2*r)-cnt;
        }
        //if(r!=0)ans+=cnt%r;
        cout<<ans<<endl;
    }
    return 0;
}

B. Kar Salesman(贪心)

题意:有n种车,第i种型号车有ai辆,每次至多买x辆不同的车,至少多少人才能卖完这些车

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void sol(){
    int n,x;cin>>n>>x;
    ll a[n+10];ll sum=0,ma=0;
    for(int i=1;i<=n;i++){
        cin>>a[i];sum+=a[i];ma=max(ma,a[i]);
    }
    cout<<max(ma,(sum+x-1)/x)<<endl;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int t;cin>>t;
    while(t--)sol();
    return 0;
}
​

C. Gerrymandering(dp)

题意:有2×n的网格,它分成连通的3个一组,每个组有超过两个投给A即投给A了,最终投给A的组最多有多少

分析:一共有七种方式,初始dp00=0,终点dp0n,用check函数判断区域内是否超过两个A

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int inf = 2e9;
int n;
bool check(int a, int b, int c) {//判断是否有两个'A'
    int p = (a == 'A'), q = (b == 'A'), r = (c == 'A');
    return (p + q + r >= 2);
}
void solve() {
    cin >> n;
    string s[2];
    cin >> s[0] >> s[1];
    vector<vector<int> > dp(2, vector<int>(n + 1, -inf));
    dp[0][0] = 0;
    //dp[i][j] 表示到达第 i 行,第 j 列时,阿尔瓦罗能获得的最大票数
    for (int i = 0; i < n; i++) {
        if (i % 3 == 0) {
            dp[0][i + 3] = max(dp[0][i + 3],
                               dp[0][i] + check(s[0][i], s[0][i + 1], s[0][i + 2])  //### 2
                               + check(s[1][i], s[1][i + 1], s[1][i + 2]));         //###
​
            dp[0][i + 1] = max(dp[0][i + 1],                                        //## 4
                               dp[0][i] + check(s[0][i], s[1][i], s[0][i + 1]));    //#.
​
            dp[1][i + 1] = max(dp[1][i + 1],                                        //#. 7
                               dp[0][i] + check(s[0][i], s[1][i], s[1][i + 1]));    //##
​
        } else if (i % 3 == 1) {//和前面还有1列的关系 必然是3整数倍+1
            if (i + 3 < n) {//若为倒数三个 必然不符合分割规律
                dp[0][i + 3] = max(dp[0][i + 3],
                                   dp[0][i] + check(s[0][i + 1], s[0][i + 2], s[0][i + 3])  //.### 3
                                   + check(s[1][i], s[1][i + 1], s[1][i + 2]));             //###.
​
                dp[1][i + 3] = max(dp[1][i + 3],
                                   dp[1][i] + check(s[0][i], s[0][i + 1], s[0][i + 2])      //###. 1
                                   + check(s[1][i + 1], s[1][i + 2], s[1][i + 3]));         //.###
            }
            dp[0][i + 2] = max(dp[0][i + 2],                                                //.# 6
                               dp[0][i] + check(s[1][i], s[1][i + 1], s[0][i + 1]));        //##
​
            dp[0][i + 2] = max(dp[0][i + 2],                                                //## 5
                               dp[1][i] + check(s[0][i], s[0][i + 1], s[1][i + 1]));        //.#
        }
    }
    cout << dp[0][n] << endl;
}
signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0); 
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

D1. Asesino (Easy Version)

题意:有一个内鬼,若干个好人和坏人,你忘记某人的身份,可以询问别人她是否为好人,1是好人,0不是好人

分析:好人认为坏人是0 坏人认为好人是0 好人认为内鬼是1 内鬼认为好人是0 内鬼认为坏人是1 坏人认为内鬼是0

代码:

#include<bits/stdc++.h>
using namespace std;
int n;
bool query(int a, int b) {
    cout << "? " << a << " " << b << endl;
    int p;
    cin >> p;
    cout << "? " << b << " " << a << endl;
    int q;
    cin >> q;
    return p != q;
}
void solve() {
    cin >> n;
    int pos = -1;
    for (int i = 1; i < n; i += 2) {//两两互问对方
        bool flag = query(i, i + 1);
        if (flag) {//存在内鬼 
            pos = i;
            break;
        }
    }
    if (pos == -1) {//没有出现内鬼 必然是奇数个最后一人
        cout << "! " << n << endl;
    } else if (query(pos, pos > 1 ? pos - 1 : pos + 2)) {
         //如果内鬼的位置不是第一个,询问内鬼和前一个参与者
        // 如果内鬼的位置是第一个,询问内鬼和后一个参与者
        cout << "! " << pos << endl;
    } else {
        cout << "! " << pos + 1 << endl;
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值