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; }