CF Div.4 Round 806传送门
Share a particularly sentence from my friend:
If you think it's hard, it means you're going up the hill again!😊🌻
A.YES or YES?
题意
会给你一个字符串 只要表示 yes 不管大小写都可以输出Yes 否则No
思路
题意即题解
code
#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
//#define double long double
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5 + 10;
const int INF = 0x3f3f3f3f;
int n, m, cnt;
int a[N];
void solve()
{
string st; cin >> st;
if (st[0] == 'Y' || st[0] == 'y')
{
if (st[1] == 'E' || st[1] == 'e')
{
if (st[2] == 'S' || st[2] == 's')
{
cout << "YES" << endl;
return;
}
}
}
cout << "NO" << endl;
}
signed main()
{
IOS;
int tt = 1; cin >> tt;
while (tt--) solve();
return 0;
}
B. ICPC Balloons
题意
ICPC区域赛AC一题会发一个气球,全场第一个做对的会额外发一个,那么给一个字符串代表全场一共做出来了哪几题,要你统计一共发了多少个气球
思路
找个 bool st[26]记录哪个字符第一次出现过则+2,其他+1即可
code
#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5 + 10;
const int INF = 0x3f3f3f3f;
int n, m, cnt;
int a[N];
bool ad[300];
void solve()
{
memset(ad, false, sizeof ad);
int n; cin >> n;
string st; cin >> st;
int cnt = 0;
for (int i = 0; i < n; i++)
{
if (ad[st[i]] == true)
{
cnt += 1;
continue;
}
if (ad[st[i]] == false)
{
ad[st[i]] = true;
cnt += 2;
}
}
cout << cnt << endl;
}
signed main()
{
IOS;
int tt = 1; cin >> tt;
while (tt--) solve();
return 0;
}
C. Cypher
题意
给你一个N位数的锁(0-9),告诉你经过一些操作后现在的状态
之后给你每一位是怎么操作的:U 和 D 分别代表向上移动和向下移动。
要你找到操作前的锁的状态
思路
反之而行 U代表要向下找 D代表要向上找
分别统计出现个数 并对10取余
最后是cntD - cntU + 那一位现在的状态
超过9和比0小都要 -10 / +10
把每一位放到vector存一下最后输出
code
#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5 + 10;
int n, m, cnt;
int a[N];
int ad[300];
void solve()
{
vector<int> ve;
int n; cin >> n;
for (int i = 1; i <= n; i++) cin >> ad[i];
for (int i = 1; i <= n; i++)
{
int si = 0; cin >> si;
string st; cin >> st;
int cntd = 0, cntu = 0;
for (int i = 0; i < si; i++)
{
if (st[i] == 'U') cntu += 1; // 向上
else cntd += 1; // d 向下
}
cntd %= 10, cntu %= 10;
int tmp = cntd - cntu;
int res = ad[i] + tmp;
if (res > 9) ve.push_back(res - 10);
else if (res < 0) ve.push_back(res + 10);
else ve.push_back(res);
}
for (auto it : ve) cout << it << ' ';
puts("");
}
signed main()
{
IOS;
int tt = 1; cin >> tt;
while (tt--) solve();
return 0;
}
D. Double Strings
题意
给你 n (1e5)个字符串 它们的长度 <= 8
你需要知道 第 i 个字符串是不是由 除 第 i 个字符串外 任意两个字符串组成的
可以是两个一样的字符串组成
如果可以找到,那么第 i 个字符串就需要你输出 1 找不到输出 0
思路
用map<string,bool> mp存一下对应字符串是否出现过
后面只需要对每一个字符串遍历能不能找得到两个子串即可
code
#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
int n, m, cnt;
int a[N];
int ad[300];
string st[N];
void solve()
{
map<string, bool> mp;
int n; cin >> n;
for (int i = 1; i <= n; i++) cin >> st[i], mp[st[i]] = true;
for (int i = 1; i <= n; i++)
{
bool flag = false;
int len = st[i].size();
for (int j = 1; j < len; j++)
{
string s1 = "", s2 = "";
for (int k = 0; k < j; k++) s1 += st[i][k];
for (int k = j; k < len; k++) s2 += st[i][k];
if (mp[s1] && mp[s2])
{
flag = true;
}
}
if (flag) cout << 1;
else cout << 0;
}
cout << '\n';
}
signed main()
{
IOS;
int tt = 1; cin >> tt;
while (tt--) solve();
return 0;
}
E. Mirror Grid
题意
首先给你一个正方形矩阵的边长
之后把这个01矩阵告诉你
它想要把这个矩阵翻转90°,180°,270° 并且原来什么样翻转完还想要什么样
为了达到这个效果 它研究出的魔法是 可以让这个01矩阵的任意位置 0->1 或 1->0
现在想要知道施展多少次这个魔法能保证翻转这些角度矩阵仍不变
思路
找到表达式即可
maze[i][j] —> maze[j][n - i + 1] —> maze[n - i + 1][n - j + 1] —> maze[n - j + 1][i]
只要统计这四个的位置1多还是0多 对小的那一方施展魔术加到cnt里面就行
需要打个bool st[i][j] 表示那四个位置都用过了
对了这个01矩阵我当成int maze[i][j]调试了半天没找到错
code
#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 110;
const int INF = 0x3f3f3f3f;
//int dx[4] = { 1,0,-1,0 }, dy[4] = {0,1,0,-1};
int n, m, cnt;
char maze[N][N];
bool st[N][N];
void solve()
{
cin >> n;
m = 4, cnt = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
cin >> maze[i][j];
if (n % 2 == 1) st[(n + 1) / 2][(n + 1) / 2] = true;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (st[i][j]) continue;
int cnt1 = 0;
if (maze[i][j] == '1') cnt1 ++;
if (maze[j][n - i + 1] == '1') cnt1 ++;
if (maze[n - i + 1][n - j + 1] == '1') cnt1 ++;
if (maze[n - j + 1][i] == '1') cnt1 ++;
st[i][j] = st[j][n - i + 1] = st[n - i + 1][n - j + 1] = st[n - j + 1][i] = true;
if (cnt1 < m - cnt1) cnt += cnt1;
else cnt += (m - cnt1);
}
}
cout << cnt << '\n';
}
signed main()
{
IOS;
int tt = 1; cin >> tt;
while (tt--)
{
memset(st, false, sizeof st);
solve();
}
return 0;
}
F. Yet Another Problem About Pairs Satisfying an Inequality
题意
给你一个数组 。请数出有多少对索引
使得
思路
化简 只需要找到一些下标满足 即可
也就是 现在要从那些可行的下标中找到符合 的几组下标
庆幸的是如果对一个而言如果
那么之前符合条件的所有
都满足
重点来了——
那么对于一个而言,如果满足了
那就说明之前所有的
都满足
所以我们只需要遍历所有可行下标的 然后找到第一个符合
的下标
也就是说 在存 一群符合题意的 i 的vector<int> ba中找到第一个大于等于的 下标idx
也就是lower_bound()这样一个二分搜索的方法 之前老以为是O(n)
res += idx 即可
code
#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<set>
#include<vector>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
//typedef pair<char, int> PCI;
//const int N = 110;
const int INF = 0x3f3f3f3f;
//const int N = 1010;
//int dx[4] = { 1,0,-1,0 }, dy[4] = {0,1,0,-1};
const int N = 2e5 + 10;
int n, m, cnt;
int a[N];
int sum[N];
void solve()
{
vector<int> ve;
vector<int> ba;
int n; cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
if (i > a[i]) ve.push_back(i);
}
int length = ve.size();
int res = 0;
for (int i = 0;i < length;i ++)
{
res += lower_bound(ba.begin(), ba.end(), a[ve[i]]) - ba.begin();
ba.push_back(ve[i]);
}
cout << res << endl;
}
signed main()
{
//IOS;
int tt = 1; cin >> tt;
while (tt--) solve();
return 0;
}
G. Good Key, Bad Key
题意
开始题看错了根本没看懂样例
你有 n个箱子。第 i 个箱子中有 ai 个硬币。你需要按照从箱子 1 号到箱子 n 号的顺序打开所有箱子。
你可以用以下两种钥匙之一打开一个箱子:
- 好钥匙:使用一次消耗 k 个硬币。
- 坏钥匙:使用时不消耗硬币,但会使所有未打开的箱子中的硬币数减半(包括正要打开的这个箱子)。
所有钥匙用过一次就会断掉(别想着买一把好钥匙开完所有箱子了),好钥匙需要重复付费,坏钥匙效果会重复计算(也就是说这个箱子价值/2,后一个箱子到它的时候价值要/4)。
思路
贪心
如果可以的话全用好钥匙,如果收益不好就先用好钥匙 后面不好的再用坏钥匙
朝着这个思路找到收益最大值 fx 如果后面坏钥匙太多了 fx / (1ll << cnt) == 0后面就没收益了
也就是说枚举要用 i 个好钥匙 用 j 枚举后面的箱子 一直加 (a[j] / (1ll << (j - i))) 直到 fx = 0
最后别忘了 res -= k * i
code
#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<set>
#include<vector>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
//typedef pair<char, int> PCI;
//const int N = 110;
const int INF = 0x3f3f3f3f;
//const int N = 1010;
//int dx[4] = { 1,0,-1,0 }, dy[4] = {0,1,0,-1};
const int N = 2e5 + 10;
int n, m, cnt;
int a[N];
int sum[N];
int res[N];
void solve()
{
int n, k; cin >> n >> k;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
sum[i] = sum[i - 1] + a[i];
}
int fw = *max_element(a + 1, a + 1 + n);
int maxid = sum[n] - n * k;
for (int i = 0; i <= n; i++)
{
int res = sum[i];
for (int j = i + 1; j <= n; j++)
{
res += (a[j] / (1ll << (j - i)));
if (fw / (1ll << (j - i)) == 0) break;
}
res -= i * k;
maxid = max(maxid, res);
}
cout << maxid << endl;
}
signed main()
{
//IOS;
int tt = 1; cin >> tt;
while (tt--) solve();
return 0;
}