SMU Spring 2023 Contest Round 1(MINEYE杯第十六届华中科技大学程序设计邀请赛)
B. Contest Preparation
对n<=m和n==0时特判一下
#include <iostream> #include <cstdio> #include <algorithm> #include <string> #include <cstring> #include <vector> #include <queue> #include <set> #include <map> #define inf 0x3f3f3f3f #define endl '\n' #define int long long using namespace std; const int N = 1e5 + 10, mod = 1e6; //typedef long long ll; typedef pair<int,int> PII; //queue<PII> q1; //priority_queue <int,vector<int>,greater<int> > q2; int n,m,t,k; int ans; /* */ void solve() { cin >> n >> m; if( !n ){ cout << 0 << endl; return; } if(n > 0 && n <= m){ cout << 2 << endl; return ; } cout << (n * 2 + m - 1) / m << endl; } signed main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); int Ke_scholar = 1; cin >> Ke_scholar; //cin.ignore(); while(Ke_scholar--) solve(); return 0; }
D. Difference
参考题解:D Difference (二分 + 单调队列) - Yaqu - 博客园 (cnblogs.com)
由于答案数据范围较大,可以考虑二分答案,要求一个区间的最大最小值,可以采用单调队列,对于每一个要求[l,r]值肯定大于[l-1,r],其max-min也一定大于后一个区间,所以我们可以对于固定的r去找他满足条件的左端点的最右值相加给ans就能得到大于等于k的区间数.
#include <map> #include <set> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <climits> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #define inf 0x3f3f3f3f #define endl '\n' #define int long long using namespace std; const int N = 1e5 + 10, mod = 1e9 +7; //typedef long long ll; typedef pair<int,int> PII; //queue<PII> q1; map<vector<int>, int > mp; //priority_queue <int,vector<int>,greater<int> > q2; int n,m,t,k; /* */ int ans; void solve() { cin >> n >> k; vector<int> v(n + 1); for(int i = 1;i <= n ;i ++){ cin >> v[i]; } auto check = [&](int x){ deque<int> dqmin,dqmax; int l = 1, ans = 0; for(int i = 1;i <= n;i ++){ while(!dqmin.empty() && v[dqmin.back()] >= v[i]) dqmin.pop_back(); dqmin.push_back(i); while(!dqmax.empty() && v[dqmax.back()] <= v[i]) dqmax.pop_back(); dqmax.push_back(i); while(l <= i && (v[dqmax.front()] - v[dqmin.front()]) * (i - l + 1) >= x){ if(dqmax.front() == l) dqmax.pop_front(); if(dqmin.front() == l) dqmin.pop_front(); l++; } ans += l - 1; } return ans >= k; }; int l = 1, r = 1e18,mid; while(l <= r){ mid = (l + r) >> 1; if(check(mid)) l = mid + 1; else r = mid - 1; } cout << r << endl; } signed main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); int Ke_scholar = 1; //cin >> Ke_scholar ; while(Ke_scholar--) solve(); return 0; }
K. Triangles
对于每一个格子被对角线平分后都能有两个个三角形(开始初始的为1,最后乘2即可),由于数据范围较小,可以直接双for去dp一下
#include <iostream> #include <cstdio> #include <algorithm> #include <string> #include <cstring> #include <vector> #include <queue> #include <set> #include <map> #define inf 0x3f3f3f3f #define endl '\n' #define int long long using namespace std; const int N = 510, mod = 1e6; //typedef long long ll; typedef pair<int,int> PII; //queue<PII> q1; //priority_queue <int,vector<int>,greater<int> > q2; int n,m,t,k; int ans; int f[N][N]; /* */ void solve() { cin >> n; for(int i = 0;i < n;i ++){ int x,y; cin >> x >> y; f[x][y] = 1; } for(int i = 0;i < N;i++){ for(int j = 0; j < N;j++){ if(f[i][j]) f[i][j] += f[i - 1][j - 1]; } } int ans = 0; for(int i = 0;i < N;i ++) for(int j = 0;j < N;j ++) ans += f[i][j]; cout << ans * 2 << endl; } signed main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); int Ke_scholar = 1; //cin >> Ke_scholar; //cin.ignore(); while(Ke_scholar--) solve(); return 0; }
M. XOR Almost Everything
当n为偶数时,一定可以全变为0,当n为奇数时,就将所有数异或起来,若为0,则YES,否则NO.
推倒:
我们可以先通过n次操作把数组全变成相同的一个数,我们下标从i=0取到i=n-1,y就选arr[i]。为什么这样可以使得数组变成相同的一个数?因为这样就相当于使得数组中的每一个数,将除了自己以外的元素都进行了异或运算。这样得到的一个数就是arr[0]^arr[1]^arr[2]……^arr[n-1]。这样每个数都会是相同的,而且这个数就是这个式子得到的结果。
异或运算有两个性质:异或自己就相当于把自己变成0;异或同一个数两次就相当于没异或。
我们再取下标i=0到i=n-1进行操作,y就取arr[0]^arr[1]^arr[2]……^arr[n-1],即现在数组都相同的那个数,这样会使得数组每个元素进行了n-1次运算,当n-1是偶数时,相当于没异或,数组的值不变;当n-1是奇数时,相当于每个元素都异或了一下自身,变成0.
所以当n-1是奇数时,我们必然能把数组变成全是0;而n-1是偶数时,数组的值不会改变,除非arr[0]^arr[1]^arr[2]……^arr[n-1]等于0,这样在一开始把数组变成相同的时候数组就全是0了,其余情况都不能把数组变成0.
原题解:HUSTPC 2022:M、XOR Almost Everything - 掘金 (juejin.cn)
#include <iostream> #include <cstdio> #include <algorithm> #include <string> #include <cstring> #include <vector> #include <queue> #include <set> #include <map> #define inf 0x3f3f3f3f #define endl '\n' #define int long long using namespace std; const int N = 1e5 + 10, mod = 1e6; //typedef long long ll; typedef pair<int,int> PII; //queue<PII> q1; //priority_queue <int,vector<int>,greater<int> > q2; int n,m,t,k; int ans,a[N]; /* */ void solve() { cin >> n; for(int i = 1;i <= n; i++){ cin >> a[i]; ans ^= a[i]; } if(ans == 0 || n % 2 == 0) cout << "YES" << endl; else cout << "NO" << endl; } signed main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); int Ke_scholar = 1; //cin >> Ke_scholar; //cin.ignore(); while(Ke_scholar--) solve(); return 0; }