链接:Codeforces Round 984 (Div. 3)
A:Quintomania
大意:
相邻数差的绝对值是否全是5或7
思路:
直接求
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define pb push_back
#define vi vector<int>
#define vii vector<pair<int, int>>
#define ff first
#define ss second
// ++ ~! */+- <<>> <> == &^| &&|| =
void solve()
{
int n;cin >> n;
vi a(n);
for (int i = 0; i < n; i++)cin >> a[i];
for (int i = 1; i < n; i++)
{
int num = abs(a[i] - a[i - 1]);
if (num != 5 && num != 7)
{
cout << "NO" << endl;
return;
}
}
cout << "YES" << endl;
}
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) solve();
return 0;
}
/* /\_/\
* (= ._.)
* / > \>
*/
B:Startup
大意:
往货架里放饮料,同种放一起,问取k个货架的最大价值
思路:
把每种的累计一下,然后就从大到小加到ans里面
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define pb push_back
#define vi vector<int>
#define vii vector<pair<int, int>>
#define ff first
#define ss second
// ++ ~! */+- <<>> <> == &^| &&|| =
void solve()
{
int n, k;cin >> n >> k;
map<int, int>mp;
for (int i = 1; i <= k; i++)
{
int a, b;cin >> a >> b;
mp[a] += b;
}
vi v;
for (auto i : mp)v.push_back(i.second);
sort(v.begin(), v.end(), greater<int>());
if (n > v.size())n = v.size();
int ans = 0;
for (int i = 0; i < n; i++)ans += v[i];
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) solve();
return 0;
}
/* /\_/\
* (= ._.)
* / > \>
*/
C:Anya and 1100
大意:
一个01字符串,每次修改一个数,然后求1100是否在字符串中
思路:
维护一个数组st[i],表示从i开始是否为1100,记录1100个数,每次修改的时候去掉对应4个位置的贡献,再加上修改后对应位置的贡献即可
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define pb push_back
#define vi vector<int>
#define vii vector<pair<int, int>>
#define ff first
#define ss second
// ++ ~! */+- <<>> <> == &^| &&|| =
void solve()
{
string k;cin >> k;
int n = k.size();
map<int, bool>st;
int cnt = 0;
k = ' ' + k;
for (int i = 1; i <= n - 3; i++)
{
if (k.substr(i, 4) == "1100")
{
st[i] = true;
cnt++;
}
}
int q;cin >> q;
while (q--)
{
int id, c;
cin >> id >> c;
k[id] = c + '0';
for (int i = id; i >= id - 3 && i > 0; i--)
{
cnt -= st[i];
st[i] = false;
if (k.substr(i, 4) == "1100")
{
st[i] = true;
cnt++;
}
}
if (cnt)cout << "YES" << endl;
else cout << "NO" << endl;
}
}
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) solve();
return 0;
}
/* /\_/\
* (= ._.)
* / > \>
*/
D:I Love 1543
大意:
给一个二维数组,问从外到内每一层顺时针旋转出现1543的个数
思路:
一个一个check,找旋转方向,看看是否为1543的开头即可,(写得有点急了,可能有更好的方法)
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define pb push_back
#define vi vector<int>
#define vii vector<pair<int, int>>
#define ff first
#define ss second
// ++ ~! */+- <<>> <> == &^| &&|| =
int idx[] = { 1, 5, 4, 3 };
int n, m;
bool check(int l, int r, vector<vector<int>>& g, int pos) //后来发现lr命名为rc更好。。。将就着看把
{
int op = idx[pos];
if (g[l][r] == idx[pos])
{
if (pos == 3)return true;
else
{
int num = min(min(l, r), min(n - l + 1, m - r + 1));
int a = n - l + 1, b = m - r + 1;
int x, y;
if (num == l && num == r)x = l, y = r + 1; //左上
else if (num == l && num == b)x = l + 1, y = r; //右上
else if (num == a && num == r)x = l - 1, y = r;// 左下
else if (num == a && num == b)x = l, y = r - 1;//右下
else if (num == l)x = l, y = r + 1;
else if (num == r)x = l - 1, y = r;
else if (num == a)x = l, y = r - 1;
else x = l + 1, y = r;
return check(x, y, g, pos + 1);
}
}
else return false;
}
void solve()
{
cin >> n >> m;
vector<vector<int>>g(n + 1, vi(m + 1));
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
char c;cin >> c;
g[i][j] = c - '0';
}
int ans = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
if (check(i, j, g, 0))ans++;
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) solve();
return 0;
}
/* /\_/\
* (= ._.)
* / > \>
*/
E:Reverse the Rivers
大意:
给个二维数组,表示每个国家每个区域的水位,然后将每个区域与上一个国家的区域连通,使得水位相或,然后找一些特定区域符合要求的编号最小的国家
思路:
刚开始还在想,这个河道连通或起来有什么用,然后看了看题暴力需要O(qmn),查询是O(1),找符合条件的是O(n),那么就至少需要把找符合条件的变成O(log),那么就需要二分找,然后想了想这怎么排序,最后看到了或操作,数越来越大,直接满足二分条件
那么,
(1)当要求 < 的时候,找小于这个数的最大编号的国家,每次取min
(2)当要求>的时候,找大于这个数的最小编号的国家,每次取max
然后我们就得到了 国家编号应小于(1)的结果,大于(2)的结果,如果两个数有交集,那么(2)的结果就是答案
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define pb push_back
#define vi vector<int>
#define vii vector<pair<int, int>>
#define ff first
#define ss second
// ++ ~! */+- <<>> <> == &^| &&|| =
void solve()
{
int n, k, q;
cin >> n >> k >> q;
vector<vector<int>> g(n + 1, vi(k + 1));
for (int i = 1; i <= n; i++)
for (int j = 1; j <= k; j++)
{
cin >> g[i][j];
g[i][j] |= g[i - 1][j];
}
while (q--)
{
int l = n, r = 1; // <=l ,>= r
int a, c;
char op;
int m;cin >> m;
while (m--)
{
cin >> a >> op >> c;
if (op == '<')
{
int ll = 0, rr = n + 1;
while (ll + 1 != rr)
{
int mid = ll + rr >> 1;
if (g[mid][a] < c)ll = mid;
else rr = mid;
}
if (g[ll][a] >= c)ll = -1;
l = min(ll, l);
}
if (op == '>')
{
int ll = 0, rr = n;
while (ll + 1 != rr)
{
int mid = ll + rr >> 1;
if (g[mid][a] > c)rr = mid;
else ll = mid;
}
if (g[rr][a] <= c)r = n + 1;
r = max(r, rr);
}
}
if (l >= r)
{
cout << r << endl;
}
else cout << -1 << endl;
}
}
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
// cin >> t;
while (t--) solve();
return 0;
}
/* /\_/\
* (= ._.)
* / > \>
*/