A.FashionabLee
题意:
正边形,通过任意旋转如果存在两条边,一条边平行于
轴,一条边平行于
轴,则输出
,否则输出
题解:
只需要是
的倍数即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 2e5 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
void solve()
{
int n;
scanf("%d", &n);
puts((n % 4) ? "NO" : "YES");
}
int main()
{
int t;
for (scanf("%d", &t); t >= 1; t--)
solve();
} B.
题意:
给定一个长度为的
串
,如果出现
这种形式,即
在前面
在后面,那么你可以选择消除
或者
中的任意一个。询问最短能消除成什么样子。
题解:
可以发现除了前导和后导
是不能删除的,中间的都可以删除,因此如果
为
,最终只剩下前导
和后导
,否则就是前导
+一个
+后导
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 1e5 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
char s[maxn];
void solve()
{
int n;
scanf("%d %s", &n, s);
int l, r;
for (l = 0; l < n; l++)
if (s[l] != '0')
break;
for (r = n - 1; r >= 0; r--)
if (s[r] != '1')
break;
for (int i = 0; i < l; i++)
putchar('0');
if (l < r)
putchar('0');
for (int i = r + 1; i < n; i++)
putchar('1');
puts("");
}
int main()
{
int t;
for (scanf("%d", &t); t >= 1; t--)
solve();
} C.RationalLee
题意:
把个数字
分给
个人,满足第
个人有
个数,使得每个人得到的最大值加最小值之和最大。如果某个人只有一个数字,他的贡献就为这个数值的两倍
题解:
将和
分别进行排序,把最大的几个数分配给
的人,然后每次取最大的一个数和最小的几个数分配给此时
最大的数即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 2e5 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
ll n, m, a[maxn], w[maxn], ans;
void solve()
{
ans = 0;
scanf("%lld%lld", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
for (int i = 1; i <= m; i++)
scanf("%lld", &w[i]);
sort(a + 1, a + n + 1);
sort(w + 1, w + m + 1);
int idx = 1;
while (w[idx] == 1)
{
ans += a[n] * 2;
n--;
idx++;
}
int l = 1;
while (idx <= m)
{
ans += a[n] + a[l];
l += w[m] - 1;
n--;
m--;
}
printf("%lld\n", ans);
}
int main()
{
int t;
for (scanf("%d", &t); t >= 1; t--)
solve();
} D. TediousLee
题意:
一开始只有一个节点,每次操作可以让没有儿子节点的节点多一个儿子,让有一个儿子节点的节点多两个儿子,一个有三个儿子节点的节点不作变化。每次操作都对每个节点同时操作,询问经过次操作,可以找出多少个不相互交叉的爪子形状(一个父节点连着三个子节点)
题解:
找找规律可以发现level 的树是一个根节点,连着两个level
的树和一个level
的树组成的。因此
的答案必然包括
,这些都是两个level
的树和一个level
的树内的,不包括根节点。通过找规律发现,当
的时候根节点可以同三个子节点相连形成一个爪子。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 2e6 + 5;
const ll mod = 1e9 + 7;
ll dp[maxn];
int main()
{
dp[1] = dp[2] = 0;
for (int i = 3; i < maxn; i++)
dp[i] = (dp[i - 1] + 2ll * dp[i - 2] + (i % 3 == 0) * 4ll) % mod;
int t, x;
for (scanf("%d", &t); t >= 1; t--)
scanf("%d", &x), printf("%lld\n", dp[x]);
return 0;
} E.DeadLee
题意:
有种食物和
个人,每种食物有
份,每个人喜欢
和
两种食物
。对于每个人如果
和
食物都有,则各吃一份;如果只有一种就只吃那一份;如果都没有就会把Lee吃了。询问Lee最终能否存活,能则输出
个人的出场顺序
题解:
反着找,先找那些每个要吃的人全都吃也不会不够的食物,让那些人只吃这个食物,那么另一样食物的需求就会减少一个,为了操作容易实现,并不是把这些人需求去掉,而是让另一种食物的数量加,结果是一样的,但是数量加
方便操作,同时把那个人加入数组,继续遍历下一个满足条件的食物,只到没有满足条件的食物或者已经满足所有人的要求则结束,以上操作用
即可。判断数组中是否有
个人,有则反向输出,否则Lee不能存活
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 5;
int n, m, w[maxn];
vector<pair<int, int>> G[maxn];
vector<int> ans;
bool vis[maxn], v[maxn];
void dfs(int x)
{
v[x] = true;
for (auto i : G[x])
{
int x = i.first, y = i.second;
w[x]++;
if (!vis[y])
ans.push_back(y), vis[y] = true;
if (!v[x] && G[x].size() <= w[x])
dfs(x);
}
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%d", &w[i]);
for (int i = 1; i <= m; i++)
{
int x, y;
scanf("%d%d", &x, &y);
G[x].push_back({y, i}), G[y].push_back({x, i});
}
for (int i = 1; i <= n; i++)
if (!v[i] && G[i].size() <= w[i])
dfs(i);
if (ans.size() < m)
puts("DEAD");
else
{
puts("ALIVE");
for (int i = m - 1; i >= 0; i--)
printf("%d ", ans[i]);
}
return 0;
} 
京公网安备 11010502036488号