A. Sakurako's Exam
思路: 按照 b 和 a 的奇偶性判断即可
代码:
#include <bits/stdc++.h>
using namespace std;
#pragma G++ optimize(2)
#define debug(x) cout << "[debug] " #x << " = " << x << '\n';
#define ull unsigned long long
#define double long double
#define int long long
typedef pair<int, int> PII;
const int inf = 0x3f3f3f3f3f3f3f3f;
const int N = 2e6 + 7;
const int P = 131;
int a, b;
void solve()
{
cin >> a >> b;
if(b & 1){
if(a < 2){ // 不能处理剩下的 2
cout << "NO" << '\n';
}else {
cout << ((a - 2) & 1 ? "NO" : "YES") << '\n';
}
}else {
cout << (a & 1 ? "NO" : "YES") << '\n';
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T;
// T = 1;
cin >> T;
while (T--)
{
solve();
}
return 0;
}
B. Square or Not
思路:模拟,将给出的字符串 转换成 二维数组然后判断即可.
代码:
#include <bits/stdc++.h>
using namespace std;
#pragma G++ optimize(2)
#define debug(x) cout << "[debug] " #x << " = " << x << '\n';
#define ull unsigned long long
#define double long double
#define int long long
typedef pair<int, int> PII;
const int inf = 0x3f3f3f3f3f3f3f3f;
const int N = 2e6 + 7;
const int P = 131;
string s;
int n;
void solve()
{
cin >> n;
cin >> s;
int t = sqrt(n);
if(t*t == n){ // 需要是平方数
bool ok = true;
string st[t];
int id = 0;
for (int i = 0; i < t;i++){
for (int j = 0; j < t;j++){
st[i].push_back(s[id++]);
}
}
for (int i = 0; i < t;i++){
for (int j = 0; j < t;j++){
if(i==0 || j==0 || i==t-1 || j==t-1){
if(st[i][j]!='1'){
ok = false;
break;
}
}else {
if(st[i][j]!='0'){
ok = false;
break;
}
}
}
if(!ok){
break;
}
}
cout << (ok == true ? "Yes" : "No") << '\n';
}else {
cout << "No" << '\n';
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T;
// T = 1;
cin >> T;
while (T--)
{
solve();
}
return 0;
}
C. Longest Good Array
思路:暴力枚举 , cnt <= sqrt(1e9) ,所以可以过
代码:
#include <bits/stdc++.h>
using namespace std;
#pragma G++ optimize(2)
#define debug(x) cout << "[debug] " #x << " = " << x << '\n';
#define ull unsigned long long
#define double long double
#define int long long
typedef pair<int, int> PII;
const int inf = 0x3f3f3f3f3f3f3f3f;
const int N = 2e6 + 7;
const int P = 131;
int a, b, c;
void solve()
{
cin >> a >> b;
int cnt = 0;
int t = 0;
while(a+t <= b){
cnt++;
a += t;
t++;
}
cout << cnt << '\n';
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T;
// T = 1;
cin >> T;
while (T--)
{
solve();
}
return 0;
}
D. Sakurako's Hobby
思路: 手推后容易发现可以分成几个连通块,对于连通块内部的 cnt 是相同,所以建边后跑一遍 dfs1 找出当前连通块的个数 sz,然后跑一遍 dfs2 将 sz 赋给 连通块内的点.
#include <bits/stdc++.h>
using namespace std;
#pragma G++ optimize(2)
#define debug(x) cout << "[debug] " #x << " = " << x << '\n';
#define ull unsigned long long
#define double long double
#define int long long
typedef pair<int, int> PII;
const int inf = 0x3f3f3f3f3f3f3f3f;
const int N = 2e6 + 7;
const int P = 131;
int n;
vector<int> e[N];
bool book[N];
bool vis[N];
int cnt[N];
int sz;
string s;
void dfs1(int x){
if(s[x]=='0'){
sz++;
}
book[x] = true;
for(int u : e[x]){
if(book[u]==false){
dfs1(u);
}
}
}
void dfs2(int x){
cnt[x] = sz;
vis[x] = true;
for(int u : e[x]){
if(vis[u]==false){
dfs2(u);
}
}
}
void solve()
{
cin >> n;
for (int i = 1; i <= n;i++){
int x;
cin >> x;
e[i].push_back(x);
book[i] = false;
vis[i] = false;
cnt[i] = 0;
}
cin >> s;
s = " " + s ;
for (int i = 1; i <= n;i++){
if(book[i]==false){
book[i] = true;
sz = 0;
dfs1(i);
dfs2(i);
}
}
for (int i = 1; i <= n;i++){
cout << cnt[i] << " ";
}
cout << '\n';
for (int i = 1; i <= n;i++){ // 清空数组
e[i].clear();
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T;
// T = 1;
cin >> T;
while (T--)
{
solve();
}
return 0;
}
E. Alternating String
思路: 对于 n 是偶数容易处理,对于n 是奇数,我们需要判断删掉位置 i处的字符对答案的影响,使用前缀和与后缀和记录 奇数位置与偶数位置字符出现的次数. 如果删除 i ,那么 i+1~n 的位置的奇偶性就变了,求其中答案的最小值即可. 具体看代码.
代码:
#include <bits/stdc++.h>
using namespace std;
#pragma G++ optimize(2)
#define debug(x) cout << "[debug] " #x << " = " << x << '\n';
#define ull unsigned long long
#define double long double
#define int long long
typedef pair<int, int> PII;
const int inf = 0x3f3f3f3f3f3f3f3f;
const int N = 3e5 + 7;
const int P = 131;
// 贪心
int n;
string s;
int pre1[N][26], pre2[N][26], last1[N][26], last2[N][26];
void solve()
{
cin >> n;
cin >> s;
if (s.length() & 1){ // 必须使用操作1
// 删除 i 后 i+1 ~ n-1的奇偶性改变
if(s.length()==1){
cout << "1" << '\n';
}else {
s = " " + s;
for (int i = 0; i <= n+100;i++){
for (int j = 0; j < 26;j++){
pre1[i][j] = pre2[i][j] = last1[i][j] = last2[i][j] = 0;
}
}
for (int i = 1; i <= n;i++){
if(i & 1){
for (int j = 0; j < 26;j++){
pre1[i][j] = pre1[i - 1][j];
pre2[i][j] = pre2[i - 1][j];
}
pre1[i][s[i] - 'a']++;
}else {
for (int j = 0; j < 26;j++){
pre1[i][j] = pre1[i - 1][j];
pre2[i][j] = pre2[i - 1][j];
}
pre2[i][s[i] - 'a']++;
}
}
for (int i = n; i >= 1;i--){
if(i & 1){
for (int j = 0; j < 26;j++){
last1[i][j] = last1[i + 1][j];
last2[i][j] = last2[i + 1][j];
}
last1[i][s[i] - 'a']++;
}else {
for (int j = 0; j < 26;j++){
last1[i][j] = last1[i + 1][j];
last2[i][j] = last2[i + 1][j];
}
last2[i][s[i] - 'a']++;
}
}
int res = 1e18;
for (int i = 1; i <= n;i++){
int k1[26] = {0}, k2[26] = {0};
for (int j = 0; j < 26;j++){
k1[j] += pre1[i - 1][j];
k2[j] += pre2[i - 1][j];
k1[j] += last2[i + 1][j];
k2[j] += last1[i + 1][j];
}
int mx1 = 0, mx2 = 0;
for (int j = 0; j < 26;j++){
mx1 = max(mx1, k1[j]);
mx2 = max(mx2, k2[j]);
}
int t = (n - 1) - mx1 - mx2;
res = min(res, t);
}
cout << (res + 1) << '\n';
}
}else {
// 不能使用操作一
int k = n / 2;
int ch1[26] = {0}, ch2[26] = {0};
for (int i = 0; i < n;i++){
if(i & 1){
ch1[s[i] - 'a']++;
}else {
ch2[s[i] - 'a']++;
}
}
int mx1 = 0, mx2 = 0;
for (int i = 0; i < 26;i++){
mx1 = max(mx1, ch1[i]);
mx2 = max(mx2, ch2[i]);
}
int res = (k - mx1) + (k - mx2);
cout << res << '\n';
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T;
// T = 1;
cin >> T;
while (T--)
{
solve();
}
return 0;
}
F. Sakurako's Box
思路: 注意取模,可能会爆long long
代码:
#include <bits/stdc++.h>
using namespace std;
#pragma G++ optimize(2)
#define debug(x) cout << "[debug] " #x << " = " << x << '\n';
#define ull unsigned long long
#define double long double
#define int long long
typedef pair<int, int> PII;
const int inf = 0x3f3f3f3f3f3f3f3f;
const int N = 2e6 + 7;
const int P = 131;
const int Mod = 1e9 + 7;
int qsm(int a,int b){
int ans = 1;
a %= Mod;
while(b){
if(b & 1){
ans = ((ans%Mod) * a % Mod) % Mod;
}
b /= 2;
a = ((a % Mod) * (a % Mod)) % Mod;
}
return ans % Mod;
}
int n;
int a[N];
int sum[N];
void solve()
{
cin >> n;
int k = (n * (n - 1)) / 2;
for (int i = 1; i <= n;i++){
cin >> a[i];
}
int ni = qsm(k, Mod - 2)%Mod;
for (int i = 0; i <= n + 100;i++){
sum[i] = 0;
}
for (int i = n; i >= 1;i--){
sum[i] =((sum[i + 1]%Mod) + a[i]%Mod) % Mod;
}
int res = 0;
for (int i = 1; i <= n;i++){
res = ((res % Mod) + ((a[i] % Mod) * (sum[i + 1] % Mod)) % Mod);
}
int ans = (res * (ni % Mod)) % Mod;
cout << (ans % Mod) << '\n';
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T;
// T = 1;
cin >> T;
while (T--)
{
solve();
}
return 0;
}
G. Sakurako's Task
思路: g 是整个数组的 gcd , 经过若干次操作后所有数字元素都可以变成 g, 求最大可能值,就尽可能的利用这 n 个数 , 将数组变成 0 ,g ,2g, .... ,(n-1)g,然后取第k 个 mex 即可,n==1时需要特判.
代码:
#include <bits/stdc++.h>
using namespace std;
#pragma G++ optimize(2)
#define debug(x) cout << "[debug] " #x << " = " << x << '\n';
#define ull unsigned long long
#define double long double
#define int long long
typedef pair<int, int> PII;
const int inf = 0x3f3f3f3f3f3f3f3f;
const int N = 2e6 + 7;
const int P = 131;
int n, k;
int a[N];
void solve()
{
cin >> n >> k;
for (int i = 1; i <= n;i++){
cin >> a[i];
}
int g = 0;
for (int i = 1; i <= n;i++){
g = __gcd(a[i], g);
}
if(n==1){
if(a[1] >= k){
cout << k-1 << '\n';
return;
}else {
cout << k << '\n';
return;
}
}else {
int t = 0;
for (int i = 1; i <= n;i++){
a[i] = t * g;
t++;
}
for (int i = 2; i <= n;i++){
int ca = a[i] - a[i - 1]-1;
if(k > ca){
k -= ca;
}else {
cout << a[i-1] + k << '\n';
return;
}
}
cout << a[n] + k << '\n';
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T;
//T = 1;
cin >> T;
while (T--)
{
solve();
}
return 0;
}