比赛情况
怒切 \(A,B,C,D\),后面 \(E,F\)
比赛总结
事实证明:
- 比赛前喝一瓶抗疲劳饮料对比赛状态的进入有显著效果。
- 比赛有人陪着打对AC题目有显著效果。
说正经的:
- 不要紧张,也不要太过放松。这样才有利于发挥出真实水平。
下面就开始 喜闻乐见
A
入门题
枚举找到最近的可用楼层即可。用 \(STL\) 里面的 map
判断一个楼层是否可用使用。
Code
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
inline int read() {
int x=0,f=1; char ch=getchar();
while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); }
return x * f;
}
int n,S,K,ans;
void work() {
map<int,bool> vis;
n = read(), S = read(), K = read(); ans = INF;
for(int i=1,x;i<=K;++i) {
x = read(); vis[x] = 1;
}
for(int j=0;S+j<=n||S-j>=1;++j) {
if(S+j <= n && !vis[S+j]) {
ans = j; break;
}
if(S-j >= 1 && !vis[S-j]) {
ans = j; break;
}
}
printf("%d\n",ans);
}
int main()
{
int T = read();
while(T--) work();
return 0;
}
B
贪心题
假设最优策略是:每次选一个人答错,当前剩下 \(s\) 个人时的收益就是 \(\frac{1}{s}\),答案就是 \(\sum_{i=1}^n \frac{1}{i}\)。
用数学归纳法证明这个猜想的正确性(其实也可以手动模拟+感性理解qwq)
证明:
对于 \(n=1\),答案是 \(\frac{1}{1}\),显然成立。
对于任意 \(k,k>1\),假设对 \(k-1\) 成立,下面我们证明对 \(k\) 也成立。
\(k-1\) 时的最大收益是 \(\sum_{i=1}^{k-1} \frac{1}{i}\)
如果 \(k\) 回合不取 \(\frac{1}{k}\),而是取任意正整数 \(r,r>1,\frac{r}{k}\),那么答案就是 \(\frac{r}{k}+\sum_{i=1}^{k-r}\),然而 \(\sum_{i=k-r+1}^k \frac{1}{i} > \frac{r}{k}\) (因为可以把右边写成 \(\sum_{i=1}^r \frac{1}{k}\),和式的项数是相同的,但是左边和式的每一项都大于等于右边的每一项)
所以对于 \(k,\frac{1}{k} + \sum_{i=1}^{k-1} \frac{1}{i}\)
(我的证明其实有些繁琐)
Code
#include<bits/stdc++.h>
using namespace std;
inline int read() {
int x=0,f=1; char ch=getchar();
while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); }
return x * f;
}
int n;
double sum=0;
int main(){
n = read();
for(double i=1;i<=n;i++){
sum += 1 / i;
}
printf("%.10f\n",sum);
}
C
模拟题
把迷宫分为上下两部分,上面部分第 \(x\) 格记做 \(m_{0,x}\),下面部分第 \(x\) 个记做 \(m_{1,x}\)。
可以发现如果 \(m_{0,x}\) 是熔岩,\(m_{1,x-1},m_{1,x},m_{1,x+1}\) 就不能是熔岩,否则就输出 No
接下来就是按题意模拟。
Code
#include<bits/stdc++.h>
using namespace std;
inline int read() {
int x=0,f=1; char ch=getchar();
while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); }
return x * f;
}
const int N = 2e5+7;
int n,q,cnt;
int vis[N],ctr[N],sto[N];
int main()
{
n = read(), q = read();
for(int i=1;i<=q;++i) {
int x = read(), y = read();
if(x == 1) {
if(vis[y] == 0) {
vis[y] = 1;
for(int j=-1;j<=1;++j)
if(y+j>=1 && y+j<=n) {
if(ctr[y+j] == 0 && sto[y+j]==1) {
++cnt;
}
ctr[y+j]++;
}
} else {
vis[y] = 0;
for(int j=-1;j<=1;++j)
if(y+j>=1 && y+j<=n) {
if(ctr[y+j] == 1 && sto[y+j]==1)
--cnt;
ctr[y+j]--;
}
}
} else {
if(sto[y] == 0) {
sto[y] = 1;
if(ctr[y]) ++cnt;
} else {
sto[y] = 0;
if(ctr[y]) --cnt;
}
}
if(!cnt) puts("Yes");
else puts("No");
}
return 0;
}
D
暴力枚举题
有一个技巧,看到 \(a_x,a_y >= 2\),这启发我们点数不会超过 \(\log_2 t\)
还有一个距离性质,因为是曼哈顿距离,我们可以一个一个点得走,从 \(i\) 点走到第 \(i+1\) 点或者是走到 \(i-1\)
这样我们的算法就呼之欲出了,枚举从起点走到一个点 \(P\),再枚举从点 \(P\)
(我还觉得这题码力有点大qwq)
注意细节,别被Hack了。
Code
#include<bits/stdc++.h>
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
inline int read() {
int x=0,f=1; char ch=getchar();
while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); }
return x * f;
}
const int N = 1007;
int t,cnt,ans;
struct Point {
int x,y;
}p[N],a,b,st;
inline int dist(Point p1,Point p2) {
return abs(p1.x-p2.x) + abs(p1.y-p2.y);
}
signed main()
{
p[0].x = read(), p[0].y = read(), a.x = read(), a.y = read(), b.x = read(), b.y = read();
st.x = read(), st.y = read(), t = read();
int X,Y,lx,ly;
for(X=a.x*p[0].x+b.x, Y=a.y*p[0].y+b.y; X<=INF && Y<=INF && X>=lx && Y>=ly; X=a.x*X+b.x,Y=a.y*Y+b.y) {
p[++cnt].x = X, p[cnt].y = Y;
lx = X, ly = Y;
//printf(" <%lld,%lld>\n",X,Y);
}
//printf("Why %lld %lld\n",X,Y);
//for(int i=0;i<=cnt;++i) printf("(%lld,%lld)\n",p[i].x,p[i].y);
//printf(" INF = %lld\n",INF);
//printf("%lld\n",cnt);
for(int i=0;i<=cnt;++i) {
int tmp = t, res = 1;
tmp -= dist(st,p[i]);
if(tmp < 0) continue;
while(tmp-dist(p[i],p[i+res]) >= 0 && i+res<=cnt) ++res;
ans = max(ans,res);
res = 1;
while(i-res>=0 && tmp-dist(p[i],p[i-res]) >= 0) ++res;
ans = max(ans,res);
}
printf("%lld\n",ans);
return 0;
}
/*
562949953421311 562949953421311 32 32 999 999
1023175 1023175 1
0
*/
E
挖坑,待补
F
挖坑,待补