A、Clam and Fish
有四种类型的池塘,类型0的池塘没有鱼也没有鱼饵,类型1的池塘没有鱼有鱼饵,类型2的池塘有鱼没有鱼饵,类型三的池塘有鱼也有鱼饵,每一天只能进行一次操作,如果你有鱼饵即使池塘没有鱼你也可以抓到鱼,如果池塘有鱼你可以不用鱼饵抓鱼,按顺序在每个池塘进行一次操作,问最多能钓多少条鱼
按题意模拟即可,将所有类型1的池塘用来作鱼饵,然后将最后剩下的鱼饵数/2 表示将后边一半的天数使用前一半的天数做鱼饵来钓鱼。
#include
using namespace std;
const int N = 2e6 + 5;
char s[N];
int main() {
int _;
scanf("%d", &_);
while (_--) {
int n;
scanf("%d", &n);
scanf("%s", s + 1);
int ls = n;
int ans = 0, t = 0;
for (int i = 1; i <= ls; i++) {
if (s[i] == '3')
ans++;
else if (s[i] == '2')
ans++;
else if (s[i] == '0') {
if (t >= 1)
ans++, t--;
}
else if (s[i] == '1')
t++;
}
printf("%d\n", ans + t / 2);
}
}
B、Classical String Problem
多次操作,每次操作将前面x个字符移到最后面或者将后面x个字符移到最前面,并且要支持查询当前的下标为x的字符
无论怎么移动,都一定是一个环,所以对于每次的移动操作,我们只需要维护一个当前起点即可。
#include
using namespace std;
typedef long long ll;
const int MAX = 2e6 + 5;
const int INF = 0x3f3f3f3f;
char s[MAX], c[MAX];
int q, x, op, len;
void solve() {
scanf("%s", s);
len = strlen(s);
scanf("%d", &q);
while (q--) {
scanf("%s%d", c, &x);
if (c[0] == 'A') {
int left = op, right = len - op;
if (x <= right) {
printf("%c\n", s[left + x - 1]);
}
else {
printf("%c\n", s[x - right - 1]);
}
}
else if (c[0] == 'M') {
op += x;
while (op < 0) op += len;
op %= len;
}
}
}
int main(void)
{
solve();
return 0;
}
C、Operation Love
给一个右手手掌的图案,可以旋转、平移,左手的图案是右手图案的对称图案,给一个图案,问你是左手图案还是右手图案。
先判断一个顺时针还是逆时针,如果是逆时针将它反转,然后判断6和9,根据谁在前面,判断是那只手的图案。
https://ac.nowcoder.com/acm/contest/view-submission?submissionId=44276347
int main()
{
int T;
sc("%d", &T);
while (T--)
{
polygon p;
p.input(20);
if (p.getdir() == 1)
{
for (int i = 1; i <= 9; i++)
swap(p.p[i], p.p[20 - i]);
}
//顺指针
vectorv;
for (int i = 0; i < 20; i++)
{
//cout << p.p[(i + 1) % 20].distance(p.p[i]) << endl;
//cout << (int)(p.p[(i + 1) % 20].distance(p.p[i]) + eps) << endl;
v.push_back(p.p[(i + 1) % 20].distance(p.p[i]));
}
for (int i = 0; i < 20; i++)
{
if (sgn(v[i] - 6) == 0 && sgn(v[(i + 1) % 20] - 9) == 0)
{
pr("left\n");
goto qwe;
}
}
pr("right\n");
qwe:;
}
}
D、Points Construction Problem
起初所有点都是黑色的,给你 n 次操作,每次操作可以将一个点变成白色,要求操作后,有 m 对点满足这一点对相邻并且颜色不同。
首先每个点可以贡献4对点对,所以我们需要考虑 x 个点构成的图案最多可以优化掉多少对点,然后可以发现,当构成正方形的时候可以优化的点对尽量多,所以我们考虑在正方形的基础上,上边加上一层右边加上一层,使其变成(n+1)*(n+1)的正方形,并以此为基础求出每个点最多可以优化的边的数量
其中 a 矩阵表示按照上述构造方法第 n 个点最多可以优化的边的数量
#include
#define ll long long
#define sc scanf
#define pr printf
using namespace std;
int a[] = { 0,0,
2,2,4,
2,4,2,4,4,
2,4,4,2,4,4,4,
2,4,4,4,2,4,4,4,4,
2,4,4,4,4,2,4,4,4,4,4,
2,4,4,4,4,4,2,4,4,4,4,4,4,
2 };
int n, m;
int tx, ty;
void print(int n)
{
for (int q = 7; q >= 1; q--)
{
if (q * q <= n)
{
for (int i = tx; i < tx + q; i++)
{
for (int j = ty; j < ty + q; j++)
{
pr("%d %d\n", i, j);
}
}
n -= q * q;
if (n <= q + 1)
{
for (int j = ty; j < ty + n; j++)
{
pr("%d %d\n", tx + q, j);
}
}
else
{
for (int j = ty; j < ty + q; j++)
{
pr("%d %d\n", tx + q, j);
}
n -= q;
for (int i = tx; i < tx + n; i++)
{
pr("%d %d\n", i, ty + q);
}
}
tx += q + 10; ty += q + 10;
break;
}
}
}
int main()
{
for (int i = 1; i <= 50; i++)
a[i] += a[i - 1];
int T;
sc("%d", &T);
while (T--)
{
tx = 1, ty = 1;
sc("%d%d", &n, &m);
if (m & 1)
{
pr("No\n");
continue;
}
if (m < 4 * n - a[n] || m > 4 * n)
{
pr("No\n");
continue;
}
pr("Yes\n");
int remain = 4 * n - m;
while (remain)
{
if (remain == 2)
{
pr("%d %d\n", 0, 1);
n--;
break;
}
for (int i = n; i >= 1; i--)
{
if (a[i] <= remain)
{
remain -= a[i];
print(i);
n -= i;
break;
}
}
}
while (n)
{
pr("%d %d\n", tx, ty);
tx += 10, ty += 10;
n--;
}
}
}
E、Two Matchings
有 n 个点,每个点一个值,要求求出两个 1 - n 的排列满足排列的任意两个相同下标的值都不同,并且这两个排列要满足下标不等于值,并且要满足两两交换,即以这个下标的值为下标的值等于这个下标,换句话来说,就是两两一组交换下标。求出按照这两个排列分成的n/2组数对的差的绝对值之和的最小值并输出
首先最小的置换一定是将数组排序后,相邻的两个数字的下标交换,考虑次小,一定是4个数字一组交换或者6个数字一组交换最优,8个一组可以拆成 4 和 4,2个一组和之前的排列重合了,所以考虑 dp ,并且4个一组的贡献是确定的(可以通过枚举来得到次小值),假设 a
#include
F、Fraction Construction Problem
T组询问,每次询问给出 a,b,求满足 的 c,d,e,f 的值,若不存在输出-1 -1 -1 -1
要求 d
先将左边通分,并且将 b 分解为两个互质的数 d、f,并且满足 d*f=b,且 d f 均不等于 1,所以题目就变成了求 c*f-e*d=a,这就是 exgcd 能解决的问题,由于要满足 c 大于0,所以若 c 小于0,c/d 增加1,e/f减少1 即可,然后记得题目中的是负号,所以给 e 加一个负号即可。(不过这里有些问题,为啥 e 后面一定是负数呢?感觉自己对于exgcd理解不够,有时间可以再学一波)
#include
#define ll long long
#define sc scanf
#define pr printf
using namespace std;
const int MAXN = 2000005;
bool vis[MAXN];
int v[MAXN];
ll gcd(ll a, ll b)
{
return b == 0 ? a : gcd(b, a % b);
}
ll exgcd(ll a, ll b, ll& x, ll& y) ///ax+by = gcd(a,b);
{
if (b == 0)
{
x = 1;
y = 0;
return a;
}
ll gcd = exgcd(b, a % b, x, y);
ll tmp = x;
x = y;
y = tmp - a / b * (y);
return gcd;
}
void init()
{
for (int i = 2; i < MAXN; i++)
{
if (vis[i] == false)
{
for (int j = i + i; j < MAXN; j = j + i)
{
vis[j] = true;
v[j] = v[j] == 0 ? i : min(v[j], i);
}
}
}
}
int main()
{
init();
int T;
sc("%d", &T);
while (T--)
{
ll a, b;
sc("%lld%lld", &a, &b);
ll g = gcd(a, b);
if (g != 1)
{
pr("%lld %lld %lld %lld\n", a / g + 1, b / g, 1LL, b / g);
}
else
{
if (v[b] == 0)
{
pr("-1 -1 -1 -1\n");
continue;
}
ll d = v[b], f = b;
while (f % d == 0)
f /= d;
d = b / f;
if (d == 1 || f == 1)
{
pr("-1 -1 -1 -1\n");
continue;
}
//c * f - e * d = a
//x y
ll c, e;
int g = exgcd(f, d, c, e);
if (a % g != 0)
{
pr("-1 -1 -1 -1\n");
}
else
{
if (c <= 0)
{
c += d;
e -= f;
}
pr("%lld %lld %lld %lld\n", c * a, d, -e * a, f);
}
}
}
}
G、Operating on a Graph
L、Problem L is the Only Lovely Problem
签到
#include
#define ll long long
#define sc scanf
#define pr printf
using namespace std;
int main()
{
string s;
cin >> s;
if (s.size() < 6)
pr("ugly");
else
{
string ss = s.substr(0, 6);
for (int i = 0; i < 6; i++)
ss[i] = tolower(ss[i]);
if (ss == "lovely")
pr("lovely");
else
pr("ugly");
}
}