Educational Codeforces Round 163 (Rated for Div. 2) - VP記錄

Jerrycyx發表於2024-10-29

Preface

這次難度感覺挺平均的,前面的題不水,後面的題也不毒瘤(可能是因為我做的不夠後面)

A. Special Characters

開局構造題。

因為特殊字元一定是成對出現的(包括兩邊的,可以分類討論思考一下),所以只有 \(n\) 為偶數的時候才有解。

然後直接以 AABBAABB... 的格式輸夠 \(n\) 個就行了。

點選檢視程式碼
#include<cstdio>
using namespace std;

int main()
{
	int T; scanf("%d",&T);
	while(T--)
	{
		int n; scanf("%d",&n);
		if(n&1) printf("NO\n");
		else
		{
			printf("YES\n");
			for(int i=1;i<=n>>1;i++)
			{
				char ch='A'+(i&1);
				putchar(ch),putchar(ch);
			}
			putchar('\n');
		}
	}
	return 0;
}

B. Array Fix

利用貪心,讓前面的數拆的儘量小,所以只要可以拆(十位大於個位且拆開後比前面打)就直接拆,最後判斷是不是不降序列。

點選檢視程式碼
#include<cstdio>
using namespace std;

const int N=55;
int n,a[N];
int m,b[N<<1];

int main()
{
	int T; scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		m=0;
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
			if(a[i]<10) b[++m]=a[i];
			else
			{
				if(a[i]/10>=b[m] && a[i]/10<=a[i]%10)
				{
					b[++m]=a[i]/10;
					b[++m]=a[i]%10;
				}
				else b[++m]=a[i];
			}
		}
		bool ans=true;
		for(int i=2;i<=m;i++)
			if(b[i]<b[i-1])
			{
				ans=false;
				break;
			}
		printf("%s\n",ans?"YES":"NO");
	}
	return 0;
}

C. Arrow Path

類似圖遍歷的處理方法,記錄每一個位置能否透過第一/二步到達,然後轉換步驟嘗試再走。

最後判斷終點是否能以第二步到達。

點選檢視程式碼
#include<cstdio>
#include<queue>
using namespace std;

const int N=2e5+5;
int n;
char str[5][N];
bool arrow[5][N];
bool f[5][N],g[5][N]; //can reach there by step 1/2
const int dx[5]={1,-1,0,0};
const int dy[5]={0,0,1,-1};

int main()
{
	int T; scanf("%d",&T);
	while(T--)
	{
		scanf("%d%s%s",&n,str[1]+1,str[2]+1);
		for(int i=1;i<=n;i++)
		{
			f[1][i]=f[2][i]=g[1][i]=g[2][i]=false;
			arrow[1][i]=str[1][i]=='>';
			arrow[2][i]=str[2][i]=='>';
			//0-'<'; 1-'>'
		}
		
		queue<pair<pair<int,int>,bool>> q;
		q.push({{1,1},0});
		while(!q.empty())
		{
			int x=q.front().first.first,y=q.front().first.second;
			bool type=q.front().second;
			q.pop();
			if(type==0) //to go step1
			{
				for(int i=0;i<4;i++)
				{
					int tx=x+dx[i],ty=y+dy[i];
					if(tx>=1&&tx<=2 && ty>=1&&ty<=n && !f[tx][ty])
					{
						f[tx][ty]=true;
						q.push({{tx,ty},1});
					}
				}
			}
			if(type==1) //to go step2
			{
				int tx=x,ty=y;
				if(arrow[x][y]) ty++;
				else ty--;
				if(tx>=1&&tx<=2 && ty>=1&&ty<=n && !g[tx][ty])
				{
					g[tx][ty]=true;
					q.push({{tx,ty},0});
				}
			}
		}
		printf("%s\n",g[2][n]?"YES":"NO");
	}
	return 0;
}

D. Tandem Repeats?

如果我告訴你我是用暴力 \(O(N^3)\) 卡過的你信嗎?

就是列舉兩段序列開頭,然後暴力判斷是否合法。

然後剪枝 + 各種反轉搜尋順序 + 猜測 Hack 資料就稀裡糊塗卡過了(\(1609\) ms)

不建議學,可以去看下正解

點選檢視程式碼
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int N=5005;
int n; char s[N];

int main()
{
	int T; scanf("%d",&T);
	while(T--)
	{
		scanf("%s",s+1);
		n=strlen(s+1);
		int ans=0;
		for(int l1=1;l1<=n&&l1<=n-(ans<<1);l1++)
		{
//			if(ans>=(n-l1+1)>>1) break;
			for(int l2=l1+((n-l1+1)>>1);l2>l1&&l2>ans+l1;l2--)
			{
//				if(ans>=l2-l1) break;
				bool flag=true;
				for(int len=l2-l1;len>=1;len--)
				{
					int p1=l1+len-1,p2=l2+len-1;
					if(!(s[p1]=='?'||s[p2]=='?' || s[p1]==s[p2]))
						{flag=false; break;}
				}
				if(flag) ans=max(ans,l2-l1);
			}
		}
		printf("%d\n",ans<<1);
	}
	return 0;
}

E. Clique Partition

正在施工……

相關文章