牛客已经开过重现赛了,想挑战的朋友可以去看看ヾ(◍°∇°◍)ノ゙
比赛传送门:重现赛
目录:
A题
题面:
题解:
BF解法
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int main() {
int n;
cin>>n;
assert(1<=n&&n<=1000000);//断言n>=1且n<=1000000,否则程序终止
int res=1;
for(int i=0;i<n;i++) res=res*2%mod;
cout<<res-1;
return 0;
}
qspow解法
#include<iostream>
using namespace std;
const long long c=1e9+7;
typedef long long ll;
ll mypow(int a,int k){
if(k==0)return 1;
a%=c;
if(k&1)return (a*mypow(a,k-1))%c;
else{
ll sub=mypow(a,k>>1);
return (sub*sub)%c; //标准的二分快速幂
}
}
int main(){
ll b;
cin>>b;
ll jie=mypow(2,b)-1;
cout<<jie<<endl;
return 0;
}
反思:
一眼就看出来杨辉三角,2^n-1
这题是作为签到题出的,可我居然耗了差不多一个半小时还没写出来。
说实话,我至今都还没想明白:为什么我这道签到题花了这么久还没做出来
我记得,我第一次是这样提交的:
#include<iostream>
using namespace std;
const long long c=1e9+7;
typedef long long ll;
ll mypow(ll k){
if(k==0)return 1;
if(k&1)return (2*mypow(k-1))%c;
else{
return mypow(k>>1)%c*mypow(k>>1)%c;
}
}
int main(){
ll b;
cin>>b;
ll jie=mypow(b)-1;
cout<<jie<<endl;
return 0;
}
[注:这段代码在重现赛上能过]
回顾:当时直接快速幂上去,以为能一遍秒过,结果惊奇地WA。(可能当时某些地方写错了吧,而我一直没发现)一遍一遍地二分快速幂,一遍一遍地改,甚至还自定义二分形式的乘法来防溢出,一遍一遍的WA,我感觉那段时间我完全在摸鱼,很着急,却一直写错。
当时,完全想的是二分快速幂是怎么错的,居然连BF解法都没试过
下场后重写,居然又完全没错了🤔。牛客回顾是一遍过啊
应该是我在打比赛时状态出问题了,这应该是所谓压力编程吧。
我还专门写过二分快速幂的文章——
《星空解题家》:二分快速幂——何为二分快速幂?二分思想解题
当然,比赛结束前半个小时还在看签到题的我~~~
很遗憾地只水了个银奖[ಥ_ಥ]
B题
题面:
题解:
补解:
#include<iostream>
#include<cmath>
using namespace std;
#define ll long long
int main(){
int t;
scanf("%d",&t);
while(t--){
ll a,b,c,d;
cin>>a>>b>>c>>d;
ll e=a*d+b*c,f=llabs(a*c-b*d);
if(!f){
e=llabs(a*d-b*c);
f=a*c+b*d;
}
printf("%lld %lld\n",e,f);
}
return 0;
}
官解:
#include<bits/stdc++.h>
using namespace std;
int main() {
#ifdef Sakuyalove
freopen("in.in", "r", stdin);
freopen("out.out", "w", stdout);
#endif
int T;
cin >> T;
assert(1 <= T && T <= (int)1e4);
while (T--) {
long long a, b, c, d;
cin >> a >> b >> c >> d;
assert(1 <= a && a <= (int)(1e9));
assert(1 <= b && b <= (int)(1e9));
assert(1 <= c && c <= (int)(1e9));
assert(1 <= d && d <= (int)(1e9));
assert(a != b || c != d);
assert(a * d != b * c || a * c != b * d);
long long e = llabs(a * c - b * d), f = a * d + b * c;
if (e == 0) {
e = llabs(a * d - b * c), f = a * c + b * d;
assert(1 <= e && e <= (long long)4e18 && 1 <= f && f <= (long long)4e18);
assert((__int128)(a * a + b * b) * (__int128)(c * c + d * d) == ((__int128)e * e + (__int128)f * f));
cout << e << ' ' << f << endl;
}
else {
assert(1 <= e && e <= (long long)4e18 && 1 <= f && f <= (long long)4e18);
assert((__int128)(a * a + b * b) * (__int128)(c * c + d * d) == ((__int128)e * e + (__int128)f * f));
cout << e << ' ' << f << endl;
}
}
return 0;
}
分析:
反思:
这道题是比较简单的,只交三次就过了。
C题
题面:
题解:
补解:
#include<iostream>
using namespace std;
typedef long long ll;
int main(){
int t;
scanf("%d",&t);
while(t--){
ll x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
ll A,B,C;
cin>>A>>B>>C;
int j1,j2;
if(A*x1+B*y1+C>0)j1=1;
else j1=-1;
if(A*x2+B*y2+C>0)j2=1;
else j2=-1;
if(j1*j2==1)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
官解:
在这里插入代码片
反思:
直接过,签到。so easy
D题
题面:
题意|分析:
关键思想:二维前缀和
在一个n*m的网格中,每个格点都有个权值,q个询问,形式为(r,c,d)表示距离点(r,c)d以内的所有点的权值和是多少?(曼哈顿距离)
1<=r<=n<=2000;
1<=c<=m<=2000;
d,q<=1e6;
点权<=1e9
像这样:
很明显,每次查询,直接暴力地找出对应各点求和是一定会超时的。所以我们很容易想到【前缀和】,不过这里前缀和换到了二维——如果每次询问是个正着摆的正方形,那我们可以直接二维前缀和维护
斜着的咋办?我们可以把网格图也一起斜着摆!
——事实上,我们可以构造一个与网格图中心重合的大正方形来恰好“框柱”原来的网格图,那么,在原图上询问的斜着的正方形就可以转化成新图中正着的正方形
——在新构造的图上维护二维前缀和即可
题解:
[1]:补解:
[2]官解:
//在一个n*m的网格中,每个格点都有个权值,q个询问,形式为(x,y,d)表示距离点(x,y)d以内的所有点的权值和是多少(曼哈顿距离)
//n,m<=2000,q<=1e6
#include<bits/stdc++.h>
using namespace std;
int n,m,q,d;
int val[4005][4005];
long long f[4005][4005];
inline int read()
{
int X=0,Y=1;char C=getchar();
while (C<'0'||C>'9') {if (C=='-') Y=-1;C=getchar();}
while (C>='0'&&C<='9') X=X*10+C-'0',C=getchar();
return X*Y;
}
int main()
{
memset(val,0,sizeof(val));
memset(f,0,sizeof(f));
n=read();m=read();q=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
val[i+j-1][n+j-i]=read();
for(int i=1;i<=n+m-1;i++)
for(int j=1;j<=n+m-1;j++)
f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+1ll*val[i][j];
for(int i=1;i<=q;i++)
{
int r,c,d;
r=read();c=read();d=read();
int lr=max(0,r+c-d-2),lc=max(0,n+c-r-d-1),rr=min(n+m-1,r+c+d-1),rc=min(n+m-1,n+c-r+d);
printf("%lld\n",f[rr][rc]-f[lr][rc]-f[rr][lc]+f[lr][lc]);
}
return 0;
}
E题
题面:
题意|分析:
题解:
[1]补解:
#include<iostream>
using namespace std;
typedef long long LL;
const int N=1e7+10,mod=998244353;
int k,q,l,r;
int cnt,prime[N];
LL f[N];
bool st[N];
int qmi(int a,int k,int p)
{
int res=1;
while(k)
{
if(k&1) res=(LL)res*a%p;
k>>=1;
a=(LL)a*a%p;
}
return res;
}
void init()
{
f[1]=1;
for(int i=2;i<N;i++)
{
if(!st[i])
{
prime[cnt++]=i;
f[i]=qmi(i,k,mod)%mod;
}
for(int j=0;prime[j]*i<N;j++)
{
int t=prime[j]*i;
st[t]=true;
f[t]=f[i]*f[prime[j]]%mod;
if(i%prime[j]==0) break;
}
}
for(int i=1;i<N;i++) f[i]+=f[i-1];
}
int main()
{
scanf("%d%d",&k,&q);
init();
while(q--)
{
scanf("%d%d",&l,&r);
printf("%d\n",(f[r]-f[l-1]+mod)%mod);
}
return 0;
}
[2]官解:
#include<bits/stdc++.h>
using namespace std;
const int M = 1e7;
const int mod = 998244353;
int qpow(int a, int p) {
int ret = 1;
while (p) {
if (p & 1) ret = 1ll * a * ret % mod;
a = 1ll * a * a % mod;
p >>= 1;
}
return ret;
}
bool np[M + 5];
int p[M + 5], num, s[M + 5];
int k, q;
signed main() {
#ifdef Sakuyalove
freopen("in.in", "r", stdin);
freopen("out.out", "w", stdout);
#endif
cin >> k >> q;
s[1] = 1;
for (int i = 2; i <= M; i++) {
if (!np[i]) {
p[++num] = i;
s[i] = qpow(i, k);
}
for (int j = 1; j <= num; j++) {
if (1ll * p[j] * i > M) break;
np[p[j] * i] = 1;
s[p[j] * i] = 1ll * s[p[j]] * s[i] % mod;
if (i % p[j] == 0) break;
}
}
for (int i = 1; i <= M; i++) s[i] = (s[i - 1] + s[i]) % mod;
while (q--) {
int l, r;
cin >> l >> r;
cout << (s[r] - s[l - 1] + mod) % mod << endl;
}
return 0;
}
F题
题面:
题意|分析:
题解:
[1]补解:
#include<iostream>
#include<cstring>
using namespace std;
const int N=1100;
int g[5][30]={
{1,2,7,8,13,14,19,20,25,26,31,32,37,38,0,4,5,10,11,16,17,22,23,28,29,34,35,40},
{0,3,6,11,13,14,16,21,24,29,31,32,34,39,2,4,5,7,12,15,20,22,23,25,30,33,38,40},
{5,7,9,11,13,14,16,18,20,22,33,35,37,39,0,6,8,10,12,15,17,19,21,32,34,36,38,40},
{0,15,17,19,21,23,25,27,29,31,33,35,37,39,14,16,18,20,22,24,26,28,30,32,34,36,38,40}
};
int cnt[N];
bool st[N];
int main()
{
string s;
while(cin>>s)
{
memset(st,false,sizeof st);
memset(cnt,0,sizeof cnt);
int ans=0;
for(int i=0;i<4;i++)
{
if(s[i]=='=')
{
for(int j=0;j<28;j++) st[g[i][j]]=true;
}
else if(s[i]=='<')
{
for(int j=0;j<14;j++) cnt[g[i][j]]--;
for(int j=14;j<28;j++) cnt[g[i][j]]++;
ans++;
}
else if(s[i]=='>')
{
for(int j=0;j<14;j++) cnt[g[i][j]]++;
for(int j=14;j<28;j++) cnt[g[i][j]]--;
ans++;
}
}
int flag=0;
for(int i=0;i<4;i++)
{
for(int j=0;j<28;j++)
{
if(!st[g[i][j]])
{
if(cnt[g[i][j]]==ans)
{
cout<<g[i][j]<<" heavy"<<endl;
flag=1;
break;
}
else if(cnt[g[i][j]]==-ans)
{
cout<<g[i][j]<<" light"<<endl;
flag=1;
break;
}
}
}
if(flag) break;
}
}
return 0;
}
[2]官解.C语言:
解法一:
#include<stdio.h>
int wt[4][28]={{1,2,7,8,13,14,19,20,25,26,31,32,37,38,0,4,5,10,11,16,17,22,23,28,29,34,35,40},
{0,3,6,11,13,14,16,21,24,29,31,32,34,39,2,4,5,7,12,15,20,22,23,25,30,33,38,40},
{5,7,9,11,13,14,16,18,20,22,33,35,37,39,0,6,8,10,12,15,17,19,21,32,34,36,38,40},
{0,15,17,19,21,23,25,27,29,31,33,35,37,39,14,16,18,20,22,24,26,28,30,32,34,36,38,40}};
int check(int t,int k,int j,char c){
int i,f,r;
for(i=f=0;!f&&i<14;++i)if(wt[t][i]==k)f=-1;
for(;!f&&i<28;++i)if(wt[t][i]==k)f=1;
if(c=='=')r=0;else if(c=='>')r=-1;else r=1;
return j*f==r;
}
int main(){
int i,j,k,f;char s[10];
while(scanf("%s",s)!=EOF){
for(i=f=1;f&&i<41;++i)
for(j=-1;f&&j<2;j+=2){
for(k=0;k<4&&check(k,i,j,s[k]);++k);
if(k<4)continue;
f=0;
printf("%d %s\n",i,j==-1?"light":"heavy");
}
}
return 0;
}
解法二:
#include <stdio.h>
char ss[2][10]={"light","heavy"};
int main(){
char s[5];
int b3[4]={1,3,9,27},i,rs,f;
while(scanf("%s",s)!=EOF){
for(i=rs=0,f=1;i<4;++i)
if(s[i]!='='){
if(s[i]=='>')rs-=b3[i];
else rs+=b3[i];
f*=-1;
}
rs*=f;
f=rs>0?1:0;
if(rs<0)rs=-rs;
printf("%d %s\n",rs,ss[f]);
}
return 0;
}
G题
题面:
题意|分析:
十六进制字符串表示的X、Y,判断2X+10和3Y+5的大小。
很明显的大整数计算,将计算结果表示出,再比较即可。
而python有专门的十六进制库,可以秒杀。
题解:
[1]补解:
#include <iostream>
#include <vector>
using namespace std;
vector<int> mul(vector<int> &A, int b)
{
vector<int> C;
int t = 0;
for (int i = 0; i < A.size() || t; i++)
{
if (i < A.size())
t += A[i] * b;
C.push_back(t % 16);
t /= 16;
}
while (C.size() > 1 && C.back() == 0)
C.pop_back();
return C;
}
vector<int> add(vector<int> &A, vector<int> &B)
{
vector<int> C;
int t = 0;
for (int i = 0; i < A.size() || i < B.size(); i++)
{
if (i < A.size())
t += A[i];
if (i < B.size())
t += B[i];
C.push_back(t % 16);
t /= 16;
}
if (t)
C.push_back(1);
return C;
}
bool gt(vector<int> &A, vector<int> &B)
{
if (A.size() != B.size())
return A.size() > B.size();
for (int i = A.size() - 1; i >= 0; i--)
{
if (A[i] != B[i])
return A[i] > B[i];
}
return false;
}
int main()
{
int t;
cin >> t;
while (t--)
{
string a;
string b;
cin >> a >> b;
vector<int> A;
for (int i = a.size() - 1; i >= 0; i--)
{
if (a[i] >= '0' && a[i] <= '9')
A.push_back(a[i] - '0');
else
A.push_back(a[i] - 'A' + 10);
}
vector<int> A1 = mul(A, 2);
vector<int> B;
for (int i = b.size() - 1; i >= 0; i--)
{
if (b[i] >= '0' && b[i] <= '9')
B.push_back(b[i] - '0');
else
B.push_back(b[i] - 'A' + 10);
}
vector<int> B1 = mul(B, 3);
vector<int> C;
C.push_back(5);
vector<int> A2 = add(A1, C);
if (gt(A2, B1))
{
cout << "Yes" << endl;
}
else
cout << "No" << endl;
}
return 0;
}
[2]官解
C++解法
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define all(x) x.begin(),x.end()
int to(char ch){
if(ch <= '9' && ch >= '0') return ch-'0';
else if(ch <= 'F' && ch >= 'A') return ch-'A'+10;
else assert(0); return 0;
}
bool f(string x, string y){
reverse(all(x)); reverse(all(y));
vector<int> a(x.size()), b(y.size());
for(int i = 0; i < x.size(); ++i) a[i] = to(x[i]), a[i] *= 2;
for(int i = 0; i < y.size(); ++i) b[i] = to(y[i]), b[i] *= 3;
a[0] += 10; b[0] += 5;
for(int i = 0; i < a.size(); ++i){
int z = a[i]/16; a[i] %= 16;
if(z){
if(i+1 == a.size()) a.pb(0);
a[i+1] += z;
}
}
for(int i = 0; i < b.size(); ++i){
int z = b[i]/16; b[i] %= 16;
if(z){
if(i+1 == b.size()) b.pb(0);
b[i+1] += z;
}
}
if(a.size() > b.size()) return true;
else if(a.size() < b.size()) return false;
else{
for(int i = (int)a.size()-1; i >= 0; --i) if(a[i] != b[i]) return a[i] > b[i];
return false;
}
}
void sol(){
int T; cin>>T;
while(T--){
string x, y;
cin>>x>>y;
if(f(x, y)) cout<<"Yes"<<'\n';
else cout<<"No"<<'\n';
}
return;
}
int main(){
sol();
// int T = 20;
// char inp[50], otp[50];
// for(int i = 1; i <= 20; ++i){
// sprintf(inp, "%d.in", i);
// sprintf(otp, "%d.out", i);
// freopen(inp, "r", stdin);
// freopen(otp, "w", stdout);
// sol();
// }
return 0;
}
python解法
T=int(input().split()[0])
for cas in range(T):
a,b=map(str,input().split())
x=int(a,16)
y=int(b,16)
if x*2+10>y*3+5:
print("Yes")
else:
print("No")
H题
题面:
题意|分析:
签到题,最基础的博弈,判断石子总数的奇偶即可
题解:
#include<iostream>
using namespace std;
int main(){
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
int sum=0;
while(n--){
int tmp;
scanf("%d",&tmp);
sum+=tmp;
}
if(sum&1)printf("Alice\n");
else printf("Bob\n");
}
return 0;
}
I题
题面:
题解:
#include<iostream>
#define maxn 5003
#define inf 998244353
using namespace std;
bool now;
int n,a[maxn],dp[2][maxn];
signed main(){
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
dp[0][0]=dp[1][0]=0;
for(int i=1;i<n;i++) dp[0][i]=dp[1][i]=-inf;
for(int i=0;i<n;i++){
now=!now;
for(int j=0;j<n;j++) dp[now][j]=dp[!now][j];
for(int j=0;j<n;j++){
dp[now][j]=max(dp[now][j],dp[!now][(j-a[i]+n)%n]+1);
}
}
// for(int i=0;i<n;i++){
// cout<<dp[now][i]<<' ';
// }
// cout<<endl;
for(int t=1;t<=n;t++){
int ans=0;
for(int i=0;i<n;i++){
if(t*i%n==0) ans=max(ans,dp[now][i]);
}
cout<<ans<<' ';
}
cout<<endl;
return EOF+1;
}
J题
题面
题意|分析:
题解:
#include<bits/stdc++.h>
#define ll long long
#define eb emplace_back
#define fi first
#define se second
using namespace std;
const int M=50009;
const int B=160;
int n,m,q,id,num;
vector<pair<int,int>>g[M];
vector<int>s[M];
int b[M];
ll ans[B<<1][M];
ll d[M];
int a[M],tid[M],dep[M],f[M<<1][23],p[M][2];
void dfs(int u,int fa){
f[tid[u]=++id][0]=u;dep[u]=dep[fa]+1;
for(auto o:g[u]){
int v=o.fi,w=o.se;
if(v!=fa){d[v]=d[u]+w;dfs(v,u);f[++id][0]=u;}
}
}
int Min(int l,int r){return dep[l]<dep[r]?l:r;}
int lca(int x,int y){
if(tid[x]>tid[y])swap(x,y);
int k=log2(tid[y]-tid[x]+1);
return Min(f[tid[x]][k],f[tid[y]-(1<<k)+1][k]);
}
ll dis(int x,int y){
int w=lca(x,y);
return d[x]+d[y]-d[w]-d[w];
}
void sol(int x){
int y=b[x];
for(int i=1;i<=m;++i){
ans[y][i]=1ll<<60;
if(s[i].size()>s[x].size()||(s[i].size()==s[x].size()&&i>x))continue;
for(auto o:s[i]){
ans[y][i]=min(ans[y][i],max({dis(o,p[i][0]),dis(o,p[i][1]),dis(o,p[x][0]),dis(o,p[x][1])}));
}
}
}
unordered_map<int,ll>mp[M];
int main(){
// freopen("20.in","r",stdin);
// freopen("1.out","w",stdout);
scanf("%d%d",&n,&m);
assert(n>=1&&n<=5e4&&m>=1&&m<=n);
for(int i=1,u,v,w;i<n;++i){
scanf("%d%d%d",&u,&v,&w);
assert(u>=1&&u<=n&&v>=1&&v<=n);
assert(w>=1&&w<=1e5);
g[u].eb(v,w);
g[v].eb(u,w);
}
dfs(1,0);
for(int j=1;j<=23;++j){
for(int i=1;i<=id-(1<<j)+1;++i){
f[i][j]=Min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}
}
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
assert(a[i]>=1&&a[i]<=m);
s[a[i]].eb(i);
p[a[i]][0]=p[a[i]][1]=i;
}
for(int i=1;i<=n;++i){
if(dis(1,i)>dis(1,p[a[i]][0]))p[a[i]][0]=i;
}
for(int i=1;i<=n;++i){
if(dis(p[a[i]][0],i)>dis(p[a[i]][0],p[a[i]][1]))p[a[i]][1]=i;
}
// for(int i=1;i<=m;++i){
// assert(s[i].size()>0);
// if(s[i].size()>B){
// b[i]=++num;
// sol(i);
// }
// }
scanf("%d",&q);
//assert(q>=1&&q<=5e4);
for(int i=1,x,y;i<=q;++i){
scanf("%d%d",&x,&y);
assert(x>=1&&x<=n&&y>=1&&y<=n&&x!=y);
if(s[x].size()<s[y].size()||(s[x].size()==s[y].size()&&x<y))swap(x,y);
if(mp[x].count(y))printf("%lld\n",mp[x][y]);
else {
ll w=1ll<<60;
for(auto o:s[y]){
w=min(w,max({dis(o,p[y][0]),dis(o,p[y][1]),dis(o,p[x][0]),dis(o,p[x][1])}));
}
mp[x][y]=w;
printf("%lld\n",w);
}
}
return 0;
}
K题
题面
题解:
#include<bits/stdc++.h>
using namespace std;
const int M=2e6+9;
int n,x,y;
int a[M],b[M],f[M],s1[M],s2[M];
bool vis[M];
int main(){
// char pt[50];
// for(int i=30;i<=37;i++){
// sprintf(pt,"%d.in",i);
// freopen(pt,"r",stdin);
// sprintf(pt,"%d.out",i);
// freopen(pt,"w",stdout);
scanf("%d",&n);
for(int i=0;i<n;++i)scanf("%d",&a[i]),b[a[i]]=i,vis[i]=0;
for(int i=0;i<n;++i){
vis[a[i]]=1;
s1[i+1]=(a[i]+n-a[i?i-1:n-1])%n;
s2[i+1]=(b[i]+n-b[i?i-1:n-1])%n;
s1[n+i+1]=s1[i+1];
s2[n+i+1]=s2[i+1];
}
for(int i=0;i<n;++i)assert(vis[i]==1);
for(int i=1,j=0;i<=n*2;f[++i]=++j)while(j&&s1[i]!=s1[j])j=f[j];
x=n*2+1-f[n*2+1];
for(int i=1,j=0;i<=n*2;f[++i]=++j)while(j&&s2[i]!=s2[j])j=f[j];
y=n*2+1-f[n*2+1];
bool bol=0;
if(x==y){
for(int i=1,j=1;i<=n*2;++i,++j){
while(j&&s1[i]!=s2[j])j=f[j];
if(j==x){bol=1;break;}
}
}
printf("%lld\n",1ll*(x+(bol?0:y))*n);
// }
return 0;
}
L题
题面:
题解:BFS
[1]补解:
#include<iostream>
#include<queue>
using namespace std;
using p=pair<int,int>;
const int N=110;
char a[N][N];
bool visited[N][N];
int mx,my,tx,ty;
int n,m;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
bool bfs(int x,int y){
queue<p>q;
q.push({x,y});
visited[x][y]=true;
while(!q.empty()){
p tmp=q.front();
q.pop();
int t1=tmp.first;
int t2=tmp.second;
if(t1==tx&&t2==ty)return true;
for(int i=0;i<4;i++){
int nx=t1+dx[i];
int ny=t2+dy[i];
if(visited[nx][ny]||nx<1||nx>n||ny<1||ny>m||a[nx][ny]=='o')continue;
q.push({nx,ny});
visited[nx][ny]=true;
}
}
return false;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)scanf("%s",a[i]+1);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]=='P'){mx=i;my=j;}
if(a[i][j]=='X'){tx=i;ty=j;}
}
}
if(bfs(mx,my))puts("Playftql");
else puts("Playftcl");
return 0;
}
[2]官解:
#include<bits/stdc++.h>
using namespace std;
const int maxn=105;
char mp[maxn][maxn];
struct nod {
int r,c;
};
int dir_r[]={1,0,-1,0};
int dir_c[]={0,1,0,-1};
int n,m;
bool check(int r,int c) {return (r>=1&&r<=n&&c>=1&&c<=m)&&mp[r][c]!='o';}
bool vis[maxn][maxn];
bool bfs(int r,int c) {
queue<nod>q;
q.push(nod{r,c});
while(!q.empty()) {
nod u=q.front();
q.pop();
if(vis[u.r][u.c]) continue;
if(mp[u.r][u.c]=='X') return 1;
vis[u.r][u.c]=1;
for(int i=0;i<4;i++) {
int tor=dir_r[i]+u.r;
int toc=dir_c[i]+u.c;
if(check(tor,toc)&&!vis[tor][toc]) {
q.push(nod{tor,toc});
}
}
}
return 0;
}
void sol() {
cin>>n>>m;
assert(1<=n&&n<=100&&1<=m&&m<=100);
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>mp[i][j];
int cntp=0,cntx=0;
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
if(mp[i][j]=='X') cntx++;
else if(mp[i][j]=='P') cntp++;
else assert(mp[i][j]=='.'||mp[i][j]=='o');
}
}
assert(cntp==1&&cntx==1);
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
if(mp[i][j]=='P') {
bool ok=bfs(i,j);
if(ok) cout<<"Playftql";
else cout<<"Playftcl";
return;
}
}
}
}
int main() {
sol();
return 0;
}
后记:
1.要及时补题
2.少刷水题,跳出舒适圈。在力扣上水简单题,不去挑战,下场是很惨的。
3.ACM很有挑战性,更多地考验思维和编程素养。还是要多多加油啊
————本图来自2019年湖南大学新生杯