2022有道小图灵信息学水平测试(四)题解

比赛地址

U

image

此题有点恶心

从小到大弄,不断复制即可

细节有点多

#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

image

因为数据很小,每个 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

image

这题我一开始没看见可以停打了一坨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

image

一看那 \(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; 
}

posted @ 2022-07-29 16:21  zhangtingxi  阅读(129)  评论(0编辑  收藏  举报