2022有道小图灵信息学水平测试(四)题解
比赛地址
U
此题有点恶心
从小到大弄,不断复制即可
细节有点多
#include<bits/stdc++.h>
using namespace std;
//#define int long long
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<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
//#define M
//#define mo
#define N 2050
int n, m, i, j, k, T;
char s[N][N];
int h;
// void cal(int x)
// {
// if(x==1) printf("@");
// else printf(" "), cal(x-1), printf("\n"), cal(x-1), printf(" "), cal(x-1), printf("\n");
// }
signed main()
{
// freopen("tiaoshi.in", "r", stdin);
// freopen("tiaoshi.out", "w", stdout);
n=read();
s[1][1]='@'; s[1][2]=' '; h=1;
for(m=1; m<n; ++m)
{
// printf("---\n");
// for(i=1; i<=h; ++i, printf("\n"))
// for(j=1; j<=(1<<n); ++j) printf("%c", s[i][j] ? s[i][j] : ' ');
// printf("--------\n");
for(i=1; i<=h; ++i)
{
for(j=1; j<=(1<<m); ++j)
s[i+h][j]=s[i+h][j+(1<<m)]=s[i][j];
}
// printf("--------\n");
for(i=1; i<=h; ++i)
for(j=(1<<(m+1)); j>=h; --j)
s[i][j]=s[i][j-h], s[i][j-h]=' ';
h<<=1;
}
// printf("--------\n");
for(i=1; i<=h; ++i, printf("\n"))
for(j=1; j<=(1<<n); ++j) printf("%c", s[i][j] ? s[i][j] : ' ');
return 0;
}
/*
@ 2^1
@
@ @ 2^2
@
@ @
@ @
@ @ @ @ 2^3
@ @
@ @ @ @
@ @ @ @
@ @ @ @ @ @ @ @
@
@ @
@ @
@ @ @ @
@ @
@ @ @ @
@ @ @ @
@ @ @ @ @ @ @ @
*/
V
因为数据很小,每个 X
都试一遍即可
注意开始结束位置相同就不用试了
#include<bits/stdc++.h>
using namespace std;
//#define int long long
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<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
//#define M
//#define mo
#define N 110
int n, m, i, j, k, T;
int lx, ly, rx, ry, a[N][N];
char s[N][N];
int dx[4]={0, 0, 1, -1};
int dy[4]={1, -1, 0, 0};
int check(int x, int y, int k)
{
// printf("%d %d\n", x, y);
if(s[x][y]=='X') return 0;
if(x==rx && y==ry) return 1;
a[x][y]=k;
int b=0, i, newx, newy;
for(i=0; i<4; ++i)
{
newx=x+dx[i];
newy=y+dy[i];
if(newx<1 || newy<1 || newx>n || newy>m) continue;
if(a[newx][newy]==k) continue;
b|=check(newx, newy, k);
}
return b;
}
signed main()
{
// freopen("tiaoshi.in", "r", stdin);
// freopen("tiaoshi.out", "w", stdout);
n=read(); m=read();
for(i=1; i<=n; ++i) scanf("%s", s[i]+1);
lx=read(); ly=read(); rx=read(); ry=read();
if(lx==rx && ly==ry) return printf("0"), 0;
if(lx<1 || ly<1 || lx>n || ly>m) return printf("-1"), 0;
if(rx<1 || ry<1 || rx>n || ry>m) return printf("-1"), 0;
if(check(lx, ly, ++k)) return printf("0"), 0;
for(i=1; i<=n; ++i)
for(j=1; j<=m; ++j)
if(s[i][j]=='X')
{
s[i][j]='O';
if(check(lx, ly, ++k)) printf("%d %d\n", i, j), T=1;
s[i][j]='X';
}
if(!T) printf("-1");
return 0;
}
W
这题我一开始没看见可以停打了一坨dp上去
显然,可顺可逆,求最小,那就bfs
#include<bits/stdc++.h>
using namespace std;
//#define int long long
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<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
//#define M
//#define mo
#define N 2000010
struct node
{
int x, y;
bool operator <(const node &A) const
{
return x>A.x;
}
};
int n, m, i, j, k, T;
int a[N], f[N], A, B, x, y;
// priority_queue<node>q;
queue<int>q;
int s_l(int A, int B)
{
// printf("%d %d\n", A, B);
// q.push(node{-1, A});
// for(i=A; i<=B; ++i)
// {
// while(q.top().y<i) q.pop();
// f[i]=q.top().x+1;
// q.push(node{f[i], i+a[i]});
// // printf("%d ", f[i]);
// }
// while(!q.empty()) q.pop();
// printf("%d\n", f[B]);
memset(f, 0x3f, sizeof(f));
f[A]=0;
for(i=A; i<=B; ++i)
if(f[i]!=f[0] && i+a[i]<=(n<<1)) f[i+a[i]]=min(f[i+a[i]], f[i]+1);
// printf("%d\n", f[B]);
return f[B];
}
int s_r(int A, int B)
{
// printf("%d %d\n", A, B);
memset(f, 0x3f, sizeof(f));
f[A]=0;
for(i=A; i>=B; --i)
if(f[i]!=f[0] && i-a[i]>=1) f[i-a[i]]=min(f[i-a[i]], f[i]+1);
// printf("%d\n", f[B]);
return f[B];
}
signed main()
{
// freopen("tiaoshi.in", "r", stdin);
// freopen("tiaoshi.out", "w", stdout);
n=read(); A=read(); B=read();
for(i=1; i<=n; ++i) a[i]=read();
if(A==B) return printf("0");
memset(f, -1, sizeof(f));
f[A]=0; q.push(A);
while(!q.empty())
{
x=q.front(); q.pop();
y=(x+a[x]-1)%n+1;
// printf("%d ", y);
if(f[y]==-1) f[y]=f[x]+1, q.push(y);
// if(y==B) return printf("%d", f[y]), 0;
y=((x-a[x]-1)%n+n)%n+1;
if(!y) y=n;
// printf("%d ", y);
if(f[y]==-1) f[y]=f[x]+1, q.push(y);
}
printf("%d", f[B]);
// if(A<B) printf("%d", (k=min(s_l(A, B), s_r(A+n, B)))==1e9 ? -1 : k);
// if(A>B) printf("%d", (k=min(s_r(A, B), s_l(A, B+n)))==1e9 ? -1 : k);
return 0;
}
X
一看那 \(O(n^2)\) 的数据,不用动脑,盲打个dp上去就行
#include<bits/stdc++.h>
using namespace std;
#define int long long
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<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
//#define M
//#define mo
#define N 1010
int n, m, i, j, k, T;
int a[N], f[N];
signed main()
{
// freopen("tiaoshi.in", "r", stdin);
// freopen("tiaoshi.out", "w", stdout);
n=read();
for(i=1; i<=n; ++i)
{
a[i]=read(); f[i]=a[i];
for(j=1; j<i; ++j)
if(a[j]>=a[i]) f[i]=max(f[i], f[j]+a[i]);
m=max(m, f[i]);
}
printf("%lld", m);
return 0;
}
本文来自博客园,作者:zhangtingxi,转载请注明原文链接:https://www.cnblogs.com/zhangtingxi/p/16532683.html