2022有道小图灵信息学水平测试(总)A-X题题解

比赛地址1

比赛地址2

比赛地址3

比赛地址4

A

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
int n, m, i, j, k, T; 
double f, mx; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	mx=1e9; 
	for(i=1; i<=8; ++i) 
		scanf("%lf", &f), mx=min(mx, f); 
	printf("%.2lf", mx); 
	return 0; 
}

B

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 1000010
int n, m, i, j, k, T; 
char s[N]; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	scanf("%s", s+1); 
	for(i=1; s[i]; ++i)
	 	if(s[i]>='0' && s[i]<='9') printf("%c", s[i]), ++k; 
	if(!k) printf("0"); 
	return 0; 
}

C

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
int n, m, i, j, k, T; 
double f; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	n=read(); 
	for(i=1; i<=n; ++i) 
	{
		scanf("%lf", &f); 
		if(f+30.7>=305) ++k; 
	}
	printf("%d", k); 
	return 0; 
}

D

image

不断循环题目所说过程,然后输出,到1就停止

#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
int n, m, i, j, k, T; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	n=read(); 
	while(n!=1)
	{
		if(n&1) n=n*3+1; 
		else n/=2;  
		printf("%lld ", n); 
	}
	return 0; 
}

E

image

统计行为1或 \(n\),列为1或 \(n\) 的和即可

#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
int n, m, i, j, k, T; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	n=read(); m=read(); 
	for(i=1; i<=n; ++i) 
		for(j=1; j<=m; ++j) 
		{
			k=read(); 
			if(i==1 || j==1 || i==n || j==m) T+=k; 
		}
	printf("%lld", T); 
	return 0; 
}

F

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
int n, m, i, j, k, T; 
double x, y; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	n=read(); 
	for(i=1; i<=n; ++i) 
	{
		scanf("%lf%lf", &x, &y); 
		if(x<89.9 || x>150.7) continue; 
		if(y<49.9 || y>90.34) continue; 
		++k; 
	}
	printf("%lld", k); 
	return 0; 
}

G

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
int n, m, i, j, k, T; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	while(n=read()) m+=n; 
	printf("%d", m); 
	return 0; 
}

H

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
int n, m, i, j, k, T; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	n=read(); 
	for(i=n; i>=1; --i, printf("\n")) 
		for(j=n; j>=1; --j) 
			printf("%c", j<=i ? '*' : ' '); 
	return 0; 
}

I

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
int n, m, i, j, k, T; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	n=read(); 
	printf("%d ", n/100), n%=100; 
	printf("%d ", n/50), n%=50; 
	printf("%d ", n/20), n%=20; 
	printf("%d ", n/10), n%=10; 
	printf("%d ", n/5), n%=5; 
	printf("%d", n/1); 
	return 0; 
}

J

image

不算博弈的博弈,显然模4为0就输,否则赢了

#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
int n, m, i, j, k, T; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	printf(read()%4 ? "Yes" : "No"); 
	return 0; 
}

K

image

看看有多少个数小于等于 \(a_k\) 即可

#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]; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	n=read(); k=read(); 
	for(i=1; i<=n; ++i) a[i]=read(); 
	for(i=1; i<=n; ++i) if(a[i]<=a[k]) ++j; 
	printf("%d", j); 
	return 0; 
}

L

image

显然,0全丢前面,1全丢后面

#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 100010
int n, m, i, j, k, T; 
char a[N]; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	n=read();
	scanf("%s", a+1); 
	// for(i=1; <=n; ++i) a[i]=read(); 
	sort(a+1, a+n+1); 
	for(i=1; i<=n; ++i) printf("%c", a[i]); 
	return 0; 
}

M

image

用个map先存起来,最后判断在不在里面即可

#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
int n, m, i, j, k, T; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	T=read(); 
	while(T--)
	{
		map<string, int>mp; 
		string s, c; 
		n=read(); 
		for(i=1; i<=n; ++i) 
		{
			cin>>s; mp[s]=1;
			c+=s[0]; 
		}
		printf(mp[c] ? "yes\n" : "no\n"); 
	}
	return 0; 
}

N

image

DP,设 \(dp(i,0/1)\) 代表前 \(i\) 枚硬币里最后一枚是反面/正面朝上的方案数

\[\Large dp(i,0)=dp(i-1,1)\\\Large dp(i,1)=dp(i-1, 0)+dp(i-1, 1) \]

#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 40
int n, m, i, j, k, T; 
int dp[N][2]; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	n=read(); 
	dp[1][1]=dp[1][0]=1; 
	for(i=2; i<=n; ++i) 
	{
		dp[i][1]=dp[i-1][1]+dp[i-1][0]; 
		dp[i][0]=dp[i-1][1]; 
	}
	printf("%lld", dp[n][0]+dp[n][1]); 
	return 0; 
}

O

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 100010
struct node
{
	int x, y, a, b, c; 
	string s; 
}a[N]; 
int n, m, i, j, k, T; 

bool cmp(node x, node y)
{
	if(x.a==y.a) {
		if(x.b==y.b) {
			if(x.c==y.c) return x.s<y.s; 
			return x.c<y.c; 
		}
		return x.b<y.b; 
	}
	return x.a<y.a; 
}

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	n=read(); 
	for(i=1; i<=n; ++i) 
	{
		m=read(); 
		for(j=1; j<=m; ++j) 
		{
			a[++k].x=i; a[k].y=j; 
			cin>>a[k].s; 
			a[k].a=read(); a[k].b=read(); a[k].c=read(); 
		}
	}
	sort(a+1, a+k+1, cmp); 
	for(i=1; i<=k; ++i) 
		cout<<a[i].s, printf(" %d %d\n", a[i].x, a[i].y); 
	return 0; 
}

P

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 18
int n, m, i, j, k, T; 
int a[N][N]; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	n=read(); 
	for(i=1; i<=n; ++i) a[i][1]=++k; 
	for(i=n, j=1; i>=1; --i, ++j)
		if(!a[i][j]) a[i][j]=++k; 
	for(i=1; i<=n; ++i)
		if(!a[i][n]) a[i][n]=++k; 
	for(i=n, j=n; i>=1; --i, --j)  
		if(!a[i][j]) a[i][j]=++k; 
	for(i=1; i<=n; ++i, printf("\n"))
		for(j=1; j<=n; ++j) 
			if(a[i][j]) printf("%5lld", a[i][j]); 
			else printf("     "); 
	return 0; 
}

Q

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 1000010
int n, m, i, j, k, T; 
char s[N]; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	scanf("%s", s+1); n=strlen(s+1); 
	for(i=n; i>=1; --i)
	{
		if(s[i]=='a' || s[i]=='e' || s[i]=='i' || s[i]=='o' || s[i]=='u') ++k; 
		else m+=k; 
	}
	printf("%lld\n", m); 
	return 0; 
}

R

image

不能理解为什么答案要用复杂的二分,明明一个map就好了

#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 1000010
int n, m, i, j, k, T; 
int a[N]; 
map<int, int>mp; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	n=read(); m=read(); 
	for(i=1; i<=n; ++i) a[i]=read(); 
	for(i=1; i<=m; ++i) mp[read()]=1; 
	for(i=1, k=0; i<=n; ++i) 
		if(mp[a[i]]) k=1, printf("%lld ", a[i]); 
	if(!k) printf("No"); 
	return 0; 
}

S

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 25
int n, m, i, j, k, T; 
int f[N][N]; 

int w(int x, int y)
{
	if(x<=0 || y<=0) return 1; 
	if(x>20 || y>20) return w(20, 20); 
	if(f[x][y]!=-1) return f[x][y]; 
	if(x<=y) return f[x][y]=w(x, y-1)+w(x, y-2); 
	else return f[x][y]=w(x-1, y)+w(x-2, y); 
}

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	memset(f, -1, sizeof(f)); 
	n=read(); m=read(); 
	while(n!=-1 || m!=-1) 
		printf("%lld\n", w(n, m)), n=read(), m=read(); 
	return 0; 
}

T

image

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 1000
int n, m, i, j, k, T; 
int a[N], b[N]; 
char s[N]; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	// k=read(); printf("%lld", k*k-k); 
	scanf("%s", s+1); n=strlen(s+1); 
	for(i=1, j=n; i<=n; ++i, --j) a[i]=s[j]-'0'; 
	for(i=1; i<=n; ++i) 
		for(j=1; j<=n; ++j) 
			b[i+j-1]+=a[i]*a[j]; 
	m=2*n-1; 
	for(i=1; i<=m; ++i) 
	{
		if(b[i]>=10) b[i+1]+=b[i]/10, b[i]%=10; 
		if(b[i+1]) m=max(m, i+1); 
	}
	while(!b[m] && m) --m; 
	for(i=1; i<=n; ++i) b[i]-=a[i]; 
	for(i=1; i<=m; ++i)
		if(b[i]<0) b[i]+=10, b[i+1]--; 
	while(!b[m] && m) --m; 
	// printf("%lld\n", m); 
	if(!m) printf("0"); 
	else {
		for(i=m; i>=1; --i) printf("%lld", b[i]); 
	}
	return 0; 
}

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:24  zhangtingxi  阅读(319)  评论(0编辑  收藏  举报