题目地址:https://atcoder.jp/contests/abc393
A - Poisonous Oyster
分支判断
#include <bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
inline void init()
{
string s1, s2;cin >> s1 >> s2;
if(s1 == s2 && s1 == "fine")cout << 4;
else if(s1 == s2 && s1 == "sick")cout << 1;
else if(s1 == "fine" && s2 == "sick")cout << 3;
else cout << 2;
}
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
init();
return 0;
}
B - A…B…C
#include <bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
inline void init()
{
string s; cin >> s;
int len = s.length();
int ans = 0;
for(int i = 0; i < len - 2; i ++)// 枚举A
{
if(s[i] != 'A')continue;
for(int j = i + 1; j < len - 1; j ++)// 枚举B
{
if(s[j] != 'B')continue;
if(j + j - i >= len)break;
if(s[j + j - i] == 'C')ans ++;// 判断C
}
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
init();
return 0;
}
C - Make it Simple
给一个无向图,要求删除所有自循环和多条边。给出一条边u=v时,直接ans++。对于没有出现的边,可以维护一个map数组,令map[u][v] = map[v][u] = 1,标记该条边。对于被标记的边直接ans++
#include <bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int N = 2e5 + 9;
map<int, int> mp[N];
inline void init()
{
int n, m;cin >> n >> m;
int ans = 0;
for(int i = 1; i <= m; i ++)
{
int u, v;cin >> u >> v;
if(u == v)ans ++;
else
{
if(mp[u][v])ans ++;
else mp[u][v] = mp[v][u] = 1;
}
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
init();
return 0;
}
D - Swap to Gather
题目要求通过相邻元素换位来使得所有的1在一起,求最少操作数。类似寻找1的重心,但分析1的移动较为困难,可分析0,那题目就转变为将所有0移到1的左边或右边。
迎面就有一个问题:对于一个0,感性的想一定是一路向左或向右移花费最少,那是应该往左移还是右移?例如110111,应该向左移动两位,即1少的一边移动。并且不难发现移动次数对应着移动方向的1的个数,这是正确的,感性的想:对于每个0都需要移到所有1的外边,移动次数就是一定不少于该侧1的个数。来个例子:111101011,0和0的换位是没有意义的,所以最优的,我们可以先移动靠右边的0两次,再移动靠左的0三次,那么答案就是1的数之和。
代码实现上,需要对于每个0快速得出其左右的1的个数,我们可以遍历01串,实时记录当前1的个数,遍历到0时就查询cnt和1的总数 - cnt
#include <bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int N = 5e5 + 9;
inline void init()
{
int _;cin >> _;
string s;cin >> s;
int n = 0, cnt = 0, ans = 0;
for(const auto &i : s)
if(i == '1')
n ++;
for(const auto &i : s)
{
if(i == '1')cnt ++;
else ans += min(cnt, n - cnt);
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
init();
return 0;
}
E - GCD of Subset
要求找包含ai的k个数字的最大公约数,暴力、直觉思路枚举ai,发现k有多少,就会有多少个for循环,复杂度接受不了。既然枚举数算公约数不行,考虑直接枚举答案,也就是枚举因子,公约数最小是1,最大不超过数组中的最大值,答案就是1到mx。
题目还要求找k个,
未完结,之后再补
// #include <bits/stdc++.h>
// #define int long long
// #define endl "\n"
// using namespace std;
//
// const int N = 1.2 * 1e6 + 9;
// int a[N], vis[N], mul[N], ans[N];
//
// inline void init()
// {
// int n, k;cin >> n >> k;
// for(int i = 1; i <= n; i ++)cin >> a[i];
// for(int i = 1; i <= n; i ++)// On
// {
// for(int j = 2; j <= a[i]; j ++)// Om
// {
// if(a[i] % j)continue;
// // 若j可以为答案,说明还有k-1个数是j的倍数
// // 记忆化遍历,需要j->是j倍数的个数
// if(!vis[j])
// {
// vis[j] = 1;
// for(int l = 1; l <= n; l ++)// On
// {
// if(a[l] % j)continue;
// mul[j] ++;
// }
// }
// if(mul[j] < k)continue;
// ans[i] = max(ans[i], j);
// }
// }
// for(int i = 1; i <= n; i ++)cout << (ans[i] ? ans[i] : 1) << endl;
// }
//
// signed main()
// {
// ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
// init();
// return 0;
// }
#include <bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int N = 1.2 * 1e6 + 9;
int a[N], cnt[N], mul[N], ans[N];
inline void init()
{
int n, k;cin >> n >> k;
for(int i = 1; i <= n; i ++)cin >> a[i];
int mx = *max_element(a + 1, a + 1 + n);
// 计算每个因子的倍数出现的次数
// for(int i = 1; i <= n; i ++)
// for(int j = 1; j <= a[i]; j ++)
// if(a[i] % j == 0)
// mul[j] ++;
for(int i = 1; i <= n; i ++)// On
cnt[a[i]] ++;
for(int i = 1; i <= mx; i ++)// Om
for(int j = i; j <= mx; j += i)// Ologm
mul[i] += cnt[j];
// 直接枚举所有可能因子
for(int i = 1; i <= mx; i ++)// Om
{
// 若因子出现数<k,则continue
// 需要统计数组中是因子倍数的个数
if(mul[i] < k)continue;
// 若可以是答案,就把因子的倍数更新
for(int j = i; j <= mx; j += i)// Ologm
ans[j] = max(ans[j], i);
}
for(int i = 1; i <= n; i ++)
cout << ans[a[i]] << endl;
}
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
init();
return 0;
}