ABC161 题解
前言
第一次很顺畅的AK呢,写篇题解纪念一下。
正文
A.ABC Swap
直接交换
B.Popular Vote
直接算算(注意不要除)
C.Replacing Integer
直接mod
D.Lunlun Number
友善的出题人给了100000的答案,我们发现总数不会很多,dfs出来排个序输出即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define N 200005
long long n, a[N], cnt = 0;
void dfs(int len, int x, ll num)
{
if(len == 10) return;
ll tmp;
for(int i = -1; i <= 1; i++)
{
int y = x + i;
if(0 <= y && y <= 9)
{
tmp = 10 * num + y;
a[++cnt] = tmp;
dfs(len + 1, y, tmp);
}
}
}
int main()
{
cin >> n;
for(int i = 1; i <= 9; i++)
{
a[++cnt] = i;
dfs(1, i, i);
}
sort(a + 1, a + cnt + 1);
cout << a[n] << endl;
return 0;
}
E.Yutori
本次比赛最难的题,但是实际上也很简单.
考虑"一定要工作的天",其实就是"不工作就不能完成的天"。再发现如果我们要让他工作最多天(不管K的限制),一定是能工作就工作最优。所以我们正着算一遍,反着算一遍,再判断一下这天不工作是否正反加起来小于k。小于k的就是我们要求的天。
#include<bits/stdc++.h>
using namespace std;
#define N 200005
int n, k, c, maxn[N], f[N], g[N], p[N];
char s[N];
bool is[N];
int main()
{
scanf("%d%d%d", &n, &k, &c);
scanf("%s", (s + 1));
for(int i = 1; i <= n; i++)
if(s[i] == 'x')
{
is[i] = 1;
}
for(int i = 1; i <= n; i++)
{
maxn[i] = maxn[i - 1];
f[i] = f[i - 1];
if(i > maxn[i] && !is[i])
{
f[i]++;
maxn[i] = i + c;
}
}
p[n + 1] = n + 1;
for(int i = n; i >= 1; i--)
{
g[i] = g[i + 1];
p[i] = p[i + 1];
if(i < p[i] && !is[i])
{
g[i]++;
p[i] = i - c;
}
}
for(int i = 1; i <= n; i++)
{
// cout << i << ' ' << f[i] << ' ' << g[i] << endl;
if(!is[i])
{
if(f[i - 1] + g[max(maxn[i - 1] + 1, i + 1)] < k)
{
printf("%d\n", i);
}
}
}
printf("\n");
return 0;
}
F.Division or Substraction
考虑答案可能是哪些数。第一是n的约数,第二是(n - 1)的约数。全部枚举一下判断即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n, ans = 0;
map <ll, bool> used;
void check(ll x)
{
// cout << x << endl;
if(x == 1) return;
ll m = n;
while(m % x == 0) m /= x;
m %= x;
if(m == 1)
{
if(!used[x])
{
ans++;
used[x] = 1;
}
}
}
int main()
{
cin >> n;
for(ll i = 1; i * i <= n; i++)
{
if(n % i == 0)
{
check(i); check(n / i);
}
}
ll m = n - 1;
for(ll i = 1; i * i <= m; i++)
{
if(m % i == 0)
{
check(i), check(m / i);
}
}
printf("%lld\n", ans);
return 0;
}