# | = | 罚时 | A | B | C | D | E | F | G | H | I | J | K | L | M | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
70 | NchuDreams |
6 | 622 | + 15 |
+ 7 |
+2 25 |
+3 173 |
-1 | +3 | +2 90 |
+2 130 |
A、Archmage
注意法师会先召唤,再恢复法力值,所以最后一天的法力值是用不上的,然后和 m 取个 min 即可
#include
#define ll long long
#define sc scanf
#define pr printf
using namespace std;
const int MAXN = 1e5 + 5;
ll a[MAXN];
int main()
{
int T;
sc("%d", &T);
while (T--)
{
ll n, m, x, y;
sc("%lld%lld%lld%lld", &n, &m, &x, &y);
ll sum = min((n + y * (m - 1)) / x, m);
pr("%lld\n", sum);
}
}
B、Bamboo Leaf Rhapsody
看案例猜题意,直接输入最短距离
#include
#define ll long long
#define sc scanf
#define pr printf
using namespace std;
const int MAXN = 1e5 + 5;
int main()
{
int n;
sc("%d", &n);
ll ans = 1e18;
ll a, b, c;
for (int i = 1; i <= n; i++)
{
sc("%lld%lld%lld", &a, &b, &c);
ans = min(ans, a * a + b * b + c * c);
}
double res = sqrt(1.0*ans);
pr("%.3lf\n", res);
}
C、Cheat Sheet
直接判断奇偶是否相同即可
#include
#define ll long long
#define sc scanf
#define pr printf
using namespace std;
mapmp;
vectorv;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, m;
cin >> n >> m;
while (m--)
{
string s;
cin >> s;
if (mp.count(s))
continue;
mp[s] = true;
v.push_back(s);
}
sort(v.begin(), v.end(), [](string q, string w) {
return q.size() < w.size();
});
int ans = -1, len = v.size();
for (int i = 0; i < len; i++)
{
ans += v[i].size() + 1;
if (ans > n)
{
cout << i;
return 0;
}
}
cout << len;
}
D、Disaster Recovery
考虑克鲁斯卡尔,将边按照边权从小到大排序,并且由 可知,如果两条边最大的点越大,边权一定大,如果相同的话,比较小的点即可。
#include
#define ll long long
#define sc scanf
#define pr printf
using namespace std;
const int MAXN = 2e5 + 5;
vectorv[MAXN];
int du[MAXN];
ll fib[MAXN];
struct node
{
int x;
int y;
}e[200005];
int que[100005];
void init()
{
for (int i = 1; i < 100005; i++)
que[i] = i;
}
int getf(int k)
{
return que[k] == k ? k : que[k] = getf(que[k]);
}
int main()
{
init();
int n, m;
sc("%d%d", &n, &m);
for (int i = 0; i < m; i++)
{
sc("%d%d", &e[i].x, &e[i].y);
if (e[i].x < e[i].y)
swap(e[i].x, e[i].y);
}
sort(e, e + m, [](node q, node w) {
if (q.x != w.x)
return q.x < w.x;
return q.y < w.y;
});
for (int i = 0; i < m; i++)
{
int f1 = getf(e[i].x), f2 = getf(e[i].y);
if (f1 != f2)
{
que[f1] = f2;
du[e[i].x]++;
du[e[i].y]++;
}
}
int ans = 0;
for (int i = 1; i <= n; i++)
ans = max(ans, du[i]);
pr("%d", ans);
}
G、Gentle Jena
每次给你一个数字,加在序列后面,并且求出当前序列的任意区间最小值之和,强制在线(n = 1e7)
显然需要一个线性时间,所以我们考虑每个数字能够贡献多少次即可,所以我们考虑维护一个单调增的序列,这样可以保证每次加入一个点,相对之前的答案的产生贡献的点都在这个单调增序列中,但是产生次数不知道,仔细思考可以发现,其实这个数字产生的次数就是这个数字在单调增序列左边的数字 和 这个数字之间的数字个数,所以每次维护一个 base 用来记录每次扩序列的增量即可。由于每个点只会被加入一次单调增序列,也只会被删除一次,所以整体复杂度是线性的。
注意取模一个是 p,一个是 998244353
#include
#define ll long long
#define sc scanf
#define pr printf
using namespace std;
const int MAXN = 1e7 + 5;
ll b[MAXN], a[MAXN];
stackst;
int main()
{
int n; ll mod, x, y, z;
sc("%d%lld%lld%lld%lld%lld", &n, &mod, &x, &y, &z, &b[1]);
ll ans = b[1];
a[1] = b[1];
st.push(0);
st.push(1);
ll base = a[1];
for (int i = 2; i <= n; i++)
{
b[i] = (x * a[i - 1] + y * b[i - 1] + z) % mod;
while (!st.empty() && b[st.top()] > b[i])
{
int tp = st.top();
st.pop();
base -= b[tp] * (tp - st.top());
}
base += b[i] * (i - st.top());
st.push(i);
a[i] = a[i - 1] + base;
a[i] %= 998244353;
ans = ans ^ a[i];
}
pr("%lld\n", ans);
}
H、Hay Mower
记录每行每列被割的最晚的时间,然后判断每个格子最晚什么时候被割即可
#include
#define ll long long
#define sc scanf
#define pr printf
using namespace std;
const int MAXN = 505;
ll s[MAXN][MAXN];
ll hang[MAXN], lie[MAXN];
const ll mod = 998244353;
int main()
{
int n, m, k;
sc("%d%d%d", &n, &m, &k);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
sc("%lld", &s[i][j]);
s[i][j] %= mod;
}
ll ans = 0;
for (int i = 1; i <= k; i++)
{
char op[2]; ll x, y;
sc("%s%lld%lld", op, &x, &y);
if (op[0] == 'r')
hang[x] = y;
else
lie[x] = y;
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
ans = (ans + s[i][j] * (max(hang[i], lie[j]) % mod)) % mod;
pr("%lld\n", ans);
}
L、Lottery Tickets
枚举最后两位数字,按照最小的顺序来枚举最后两位,然后将其他数字从大到小顺序输出。
然后特判只有一个数字的情况和全0的情况。
#include
#define ll long long
#define sc scanf
#define pr printf
using namespace std;
int a[11];
int main()
{
int T;
sc("%d", &T);
while (T--)
{
int n = 10, cnt = 0;
for (int i = 0; i < 10; i++)
{
sc("%d", &a[i]);
cnt += a[i];
}
if (cnt == 1)
{
if (a[0] == 1)
pr("0\n");
else if (a[4] == 1)
pr("4\n");
else if (a[8] == 1)
pr("8\n");
else
pr("-1\n");
continue;
}
if (cnt == a[0])
{
pr("0\n");
continue;
}
int q = -1, w = -1;
if (a[0] >= 2)
{
q = 0, w = 0;
a[0] -= 2;
}
else if (a[0] >= 1 && a[2] >= 1)
{
q = 2, w = 0;
a[0]--;
a[2]--;
}
else if (a[1] >= 1 && a[2] >= 1)
{
q = 1, w = 2;
a[1]--;
a[2]--;
}
else if (a[3] >= 1 && a[2] >= 1)
{
q = 3, w = 2;
a[3]--;
a[2]--;
}
else if (a[4] >= 1 && a[0] >= 1)
{
q = 4, w = 0;
a[4]--;
a[0]--;
}
else if (a[4] >= 1 && a[2] >= 1)
{
q = 2, w = 4;
a[4]--;
a[2]--;
}
else if (a[4] >= 2)
{
q = 4, w = 4;
a[4] -= 2;
}
else if (a[5] >= 1 && a[2] >= 1)
{
q = 5, w = 2;
a[5]--;
a[2]--;
}
else if (a[6] >= 1 && a[0] >= 1)
{
q = 6, w = 0;
a[6]--;
a[0]--;
}
else if (a[6] >= 1 && a[1] >= 1)
{
q = 1, w = 6;
a[6]--;
a[1]--;
}
else if (a[6] >= 1 && a[3] >= 1)
{
q = 3, w = 6;
a[6]--;
a[3]--;
}
else if (a[6] >= 1 && a[4] >= 1)
{
q = 6, w = 4;
a[6]--;
a[4]--;
}
else if (a[6] >= 1 && a[5] >= 1)
{
q = 5, w = 6;
a[6]--;
a[5]--;
}
else if (a[7] >= 1 && a[2] >= 1)
{
q = 7, w = 2;
a[7]--;
a[2]--;
}
else if (a[7] >= 1 && a[6] >= 1)
{
q = 7, w = 6;
a[7]--;
a[6]--;
}
else if (a[8] >= 1 && a[0] >= 1)
{
q = 8, w = 0;
a[8]--;
a[0]--;
}
else if (a[8] >= 1 && a[2] >= 1)
{
q = 2, w = 8;
a[8]--;
a[2]--;
}
else if (a[8] >= 1 && a[4] >= 1)
{
q = 8, w = 4;
a[8]--;
a[4]--;
}
else if (a[8] >= 1 && a[6] >= 1)
{
q = 6, w = 8;
a[8]--;
a[6]--;
}
else if (a[8] >= 2)
{
q = 8, w = 8;
a[8]--;
a[8]--;
}
else if (a[9] >= 1 && a[2] >= 1)
{
q = 9, w = 2;
a[9]--;
a[2]--;
}
else if (a[9] >= 1 && a[6] >= 1)
{
q = 9, w = 6;
a[9]--;
a[6]--;
}
else
{
if (a[0] >= 1)
pr("0\n");
else if (a[4] >= 1)
pr("4\n");
else if (a[8] >= 1)
pr("8\n");
else
pr("-1\n");
continue;
}
for (int i = 9; i >= 0; i--)
{
while (a[i])
{
pr("%d", i);
a[i]--;
}
}
pr("%d%d\n", q, w);
}
}