Codeforces Round #806 (Div. 4) A - G
A. YES or YES?
统一一下大小写
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
int main()
{
int t;
cin >> t;
while(t--)
{
string s;
cin >> s;
for(int i=0; i<s.length(); i++)
{
if(s[i] >= 'a' && s[i] <= 'z')
s[i] = s[i] - 'a' + 'A';
}
if(s == "YES") cout << "YES\n";
else cout << "NO\n";
}
return 0;
}
B. ICPC Balloons
找下有多少种不同的字母,再加上字符串长
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
int vis[maxn];
int main()
{
int t;
cin >> t;
while(t--)
{
int n;
string s;
cin >> n >> s;
for(int i='A'; i<='Z'; i++) vis[i] = 0;
int ans = 0;
for(int i=0; i<s.length(); i++)
{
if(vis[s[i]] == 0) ans++;
vis[s[i]] = 1;
}
ans += s.length();
cout << ans << endl;
}
return 0;
}
C. Cypher
模拟
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
int num[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
int n;
cin >> n;
for(int i=0; i<n; i++) cin >> num[i];
for(int i=0; i<n; i++)
{
int k;
string s;
cin >> k >> s;
for(int j=0; j<k; j++)
{
if(s[j] == 'D')
{
num[i]++;
if(num[i] == 10) num[i] = 0;
}
else
{
num[i]--;
if(num[i] == -1) num[i] = 9;
}
}
}
for(int i=0; i<n; i++)
{
if(i) cout << " ";
cout << num[i];
}
cout << '\n';
}
return 0;
}
D. Double Strings
长度为 8 的字符串,直接 map + 字符串分割
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
string s[maxn];
map<string, int>mp;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
mp.clear();
int n;
cin >> n;
for(int i=0; i<n; i++)
{
cin >> s[i];
mp[s[i]] = 1;
}
for(int i=0; i<n; i++)
{
string now = "";
int f = 0;
for(int j=1; f == 0 && j<s[i].length(); j++)
{
now += s[i][j-1];
if(mp[now] && mp[string(s[i], j, s[i].length() - j)])
f = 1;
}
cout << f;
}
cout << '\n';
}
return 0;
}
E. Mirror Grid
旋转四下,相当于四个位置一组,然后判断一下化为 1 好,还是化为 0 好
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 110;
const ll inf = 1e17 + 10;
int vis[maxn][maxn];
string s[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
int n;
cin >> n;
for(int i=0; i<n; i++) for(int j=0; j<n; j++) vis[i][j] = 0;
for(int i=0; i<n; i++) cin >> s[i];
int ans = 0;
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
if(vis[i][j]) continue;
int f = 0;
f += s[i][j] - '0';
vis[i][j] = 1;
f += s[n-i-1][n-j-1] - '0';
vis[n-i-1][n-j-1] = 1;
f += s[j][n-i-1] - '0';
vis[j][n-i-1] = 1;
f += s[n-j-1][i] - '0';
vis[n-j-1][i] = 1;
ans += min(f, 4 - f);
}
}
cout << ans << '\n';
}
return 0;
}
F. Yet Another Problem About Pairs Satisfying an Inequality
前缀和
找一下前 \(k\) 个符合 \(a_i < i\) 的数量,然后再枚举每一个 \(j\),每个位置上的贡献就为 pre[a_j-1]
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
ll sum[maxn];
int a[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
int n;
cin >> n;
for(int i=1; i<=n; i++)
{
cin >> a[i];
if(i > a[i]) sum[i]++;
sum[i] += sum[i-1];
}
ll ans = 0;
for(int i=1; i<=n; i++)
if(i > a[i] && a[i]) ans += sum[a[i] - 1];
cout << ans << '\n';
for(int i=0; i<=n; i++) sum[i] = 0;
}
return 0;
}
G. Good Key, Bad Key
dp 或 贪心
注意题目可负债!
因为箱子的价值不超过 \(10^9\),因此最多使用 \(32\) 次不好的钥匙之后,所有箱子的价值都会变成 \(0\)
因此有 \(dp[i][j]\) 表示在开完第 \(i\) 个箱子,用了 \(j\) 把坏钥匙之后的最大值
有转移方程:\(dp[i][j] = max(dp[i-1][j] - k + a[i][j], dp[i-1][j-1] + a[i-1][j-1])\),第一项表示用好钥匙转移,第二项表示用坏钥匙转移
如果你用了以上转移方程 wa4,则要看看下面这个
但是以上这种转移方式显然忽略了一种情况:\(j\) 的最后一层并不代表只使用 \(j\) 次,它表示使用了 \(j\) 及其 \(j\) 以上个坏钥匙
因此还应该增加一个针对于最后一层的转移方程:\(dp[i][32] = max(dp[i][32], dp[i-1][32])\)
或者答案直接选取 dp 数组里出现过的最大值,因为只要出现过,一直选坏钥匙都不会导致答案变差
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e16;
ll a[maxn][35];
ll dp[maxn][35];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
ll n, k;
cin >> n >> k;
for(int i=1; i<=n; i++) for(int j=0; j<=32; j++) dp[i][j] = -inf;
for(int i=1; i<=n; i++)
{
cin >> a[i][0];
for(int j=1; j<=32; j++)
a[i][j] = a[i][j-1] >> 1;
}
dp[0][0] = 0;
ll ans = 0;
for(int i=1; i<=n; i++)
{
dp[i][0] = dp[i-1][0] - k + a[i][0];
ans = max(ans, dp[i][0]);
for(int j=1; j<=min(32, i); j++)
{
dp[i][j] = max({dp[i][j], dp[i-1][j] - k + a[i][j], dp[i-1][j-1] + a[i][j]});
}
dp[i][32] = max(dp[i][32], dp[i-1][32]);
}
for(int i=0; i<=32; i++) ans = max(ans, dp[n][i]);
cout << ans << endl;
}
return 0;
}