A
题解:
签到题,白色便宜就打白色,彩色便宜就打彩色
代码:
#include<iostream>
#include<bits/stdc++.h>
#include<set>
#include<map>
using namespace std;
#define endl "\n"
#define ll long long
void solve(){
ll a,b,x,y;
if(x > y) b += a,a= 0;
cout<<a*x + b*y<<endl;
}
signed main(){
cin.tie(0);cout.tie(0);
ios::sync_with_stdio(0);
ll t;cin>>t;
while(t--)
solve();
}
B
题解:
贪心,每次让n变为能到达的最大的数字
如果是奇数就n/2 , 偶数就是 n/2-1
代码:
#include<iostream>
#include<bits/stdc++.h>
#include<set>
#include<map>
using namespace std;
#define endl "\n"
#define ll long long
void solve(){
ll n;cin>>n;
int ans = 0;
while(n){
if(n&1) n = n/2;
else n = n/2 - 1;
ans ++;
}
cout<<ans<<endl;
}
signed main(){
cin.tie(0);cout.tie(0);
ios::sync_with_stdio(0);
ll t;cin>>t;
while(t--)
solve();
}
C
题解:
将S能到达的地区标记为1,E能到达的地区标记为2,然后判定每个2的附近3行行列是否有1,有的话就可以直接贯穿
代码:
#include<iostream>
#include<bits/stdc++.h>
#include<set>
#include<map>
#include<queue>
using namespace std;
#define endl "\n"
#define ll long long
void solve() {
int n, m; cin >> n >> m;
vector<string> grid(n);
for (auto& x : grid) cin >> x;
queue<pair<int, int>> q;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] == 'S') {
q.push({ i,j });
}
}
}
auto msk1 = grid;
int dx[4] = { -1,1,0,0 };
int dy[4] = { 0,0,-1,1 };
while (q.size()) {
auto p = q.front(); q.pop();
int x = p.first, y = p.second;
msk1[x][y] = '1';
for (int i = 0; i < 4; i++) {
int tox = x + dx[i], toy = y + dy[i];
if (tox < 0 || tox >= n || toy < 0 || toy >= m) continue;
if (grid[tox][toy] == '#') continue;
if (msk1[tox][toy] == '1') continue;
msk1[tox][toy] = '1';
q.push({ tox,toy });
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] == 'E') {
q.push({ i,j });
}
}
}
auto msk2 = grid;
while (q.size()) {
auto p = q.front(); q.pop();
int x = p.first, y = p.second;
msk2[x][y] = '2';
for (int i = 0; i < 4; i++) {
int tox = x + dx[i], toy = y + dy[i];
if (tox < 0 || tox >= n || toy < 0 || toy >= m) continue;
if (grid[tox][toy] == '#') continue;
if (msk2[tox][toy] == '2') continue;
msk2[tox][toy] = '2';
q.push({ tox,toy });
}
}
vector<int> h1(n, 0), z1(m, 0);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (msk1[i][j] == '1') {
h1[i] = 1; z1[j] = 1;
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (msk2[i][j] == '2') {
for(int k = -1;k<=1;k++){
if(i + k >= 0 && i + k < n && h1[i+k]){
cout << "YES" << endl; return;
}
if(j + k >= 0 && j + k < n && z1[j+k]){
cout << "YES" << endl; return;
}
}
}
}
}
cout << "NO" << endl;
}
signed main() {
cin.tie(0); cout.tie(0);
ios::sync_with_stdio(0);
solve();
}
D
题解:
根据素数的稠密性,直接开一个长度为100n的数字,进行暴力剔除不满足的时间
代码:
#include<iostream>
#include<bits/stdc++.h>
#include<set>
#include<map>
using namespace std;
#define endl "\n"
#define ll long long
void solve(){
int n;cin>>n;
vector<int> a(n);
for(int&x:a) cin>>x;
int m = 100*n + 10;
vector<int> dp(m,0);
set<int> se(a.begin(),a.end());
for(int x:se){
for(int j = x; j<m;j+=x){
dp[j] = 1;
}
}
for(int i = 2;i<m;i++){
if(dp[i] == 0){
cout<<i<<endl;return;
}
}
}
signed main(){
cin.tie(0);cout.tie(0);
ios::sync_with_stdio(0);
ll t;cin>>t;
while(t--)
solve();
}
E
题解:
将能连续倒塌的多米诺骨牌看作一个块,将每个块取出来,贪心取m个就行
代码:
#include<iostream>
#include<bits/stdc++.h>
#include<set>
#include<map>
using namespace std;
#define endl "\n"
#define ll long long
void solve(){
ll n,m;cin>>n>>m;
vector<pair<ll,ll>> vp(n);
for(ll i =0;i<n;i++) cin>>vp[i].first;
for(ll i =0;i<n;i++) cin>>vp[i].second;
for(ll i =0;i<n;i++) swap(vp[i].first , vp[i].second);
sort(vp.begin(),vp.end());
vector<ll> k;
ll p = 0;
while(p < n){
ll rp = vp[p].first + vp[p].second;
ll sz = 1;
while(p + 1 < n && rp >= vp[p+1].first){
p ++;sz ++;
rp = max(rp , vp[p].first + vp[p].second);
}
p++;
k.push_back(sz);
}
sort(k.begin(),k.end());
reverse(k.begin(),k.end());
ll ans = 0;
for(ll i =0 ;i<k.size() && i < m;i++){
ans += k[i];
}
cout<<ans<<endl;
}
signed main(){
cin.tie(0);cout.tie(0);
ios::sync_with_stdio(0);
ll t;cin>>t;
while(t--)
solve();
}
F
题解:
对于每两个相邻的墙,我们能获取2*dis的时间,那么一共有2 * m的不同时间,直接进行完全背包即可
代码:
#include<iostream>
#include<bits/stdc++.h>
#include<set>
#include<map>
using namespace std;
#define endl "\n"
void solve(){
int n,m,t;cin>>n>>m>>t;
vector<int> a(m);
for(int&x:a) cin>>x;
if(n>t){
cout<<0<<endl;return;
}
sort(a.begin(),a.end());
set<int> b;
for(int i=1;i<m;i++) b.insert(a[i] - a[i-1]);
vector<int> w;
for(int x:b) w.push_back(x);
vector<int> dp(t+1,0);
dp[n] = 1;
for(int x:w){
for(int j =0;j<=t;j++){
if(j + 2*x > t) continue;
if(dp[j]){
dp[j + 2*x ] |= dp[j];
}
}
}
for(int i = t;i>=0;i--){
if(dp[i]){
cout<<i<<endl;return;
}
}
}
signed main(){
cin.tie(0);cout.tie(0);
ios::sync_with_stdio(0);
int t;cin>>t;
while(t--)
solve();
}
G
题解:
暴力维护每个时间点的各种🐟的状态,然后从x暴力跳最大能吃的,因为每次x加倍,所有跳lgw次,这个用set+离散化+树状数组维护区间sum就行
代码
#include<iostream>
#include<bits/stdc++.h>
#include<set>
#include<map>
using namespace std;
//坐标从0开始直接用的树状数组
#define ll long long
template <typename T>
class Fenwick
{
private:
ll n;
vector<T> c;
ll lowbits(ll x){
return (-x) & x;
}
ll pre_sum(ll i){
ll re = 0;
for (; i > 0; i -= lowbits(i))
re += c[i];
return re;
}
public:
explicit Fenwick<T>(vector<T> v){
this->n = v.size();
this->c = vector<T>(n+1,0);
for(ll i=0;i<n;i++)
add(i,v[i]);
};
void add(ll i, ll val){
++i;
for (;i<=n; i += lowbits(i))
c[i] += val;
}
ll range_sum(ll i,ll j){
++i;++j;
return pre_sum(j) - pre_sum(i - 1);
}
};
void solve(){
ll n,x;cin>>n>>x;
vector<vector<ll>> vp;
vector<ll> b;
for(ll i =0 ;i<n;i++){
ll l,r,y;cin>>l>>r>>y;
vp.push_back({l,y,0});
vp.push_back({r,y,1});
b.push_back(y);
}
sort(b.begin(),b.end());
map<ll,ll> mp;
// 离散化
for(ll i =0 ;i<n;i++) mp[b[i]] = i;
Fenwick<ll> fw(vector<ll>(n,0));
sort(vp.begin(),vp.end());
multiset<ll> se;
ll ans = 0;
for(ll i = 0;i<2*n;){
ll p1 = vp[i][0] , y = vp[i][1] , op = vp[i][2];
while(i<2*n && vp[i][0] == p1){
ll ny = vp[i][1] , nop = vp[i][2];
if(nop==0){
se.insert(ny);
fw.add(mp[ny],ny);
}else{
se.erase(se.find(ny));
fw.add(mp[ny],-ny);
}
i++;
}
// 找答案
ll tval = x;
ll pos = 0;
while(1){
auto it = se.lower_bound(tval);
if(it==se.end()){
tval += fw.range_sum(pos,n-1);break;
}
if(*it > tval){
if(it==se.begin()) break;
it = prev(it);
}
ll pr = mp[*it];
if(pr < pos) break;
tval += fw.range_sum(pos , pr);
pos = pr + 1;
}
ans = max(ans, tval);
}
cout<<ans<<endl;
}
signed main(){
cin.tie(0);cout.tie(0);
ios::sync_with_stdio(0);
ll t;cin>>t;
while(t--)
solve();
}
******************************