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

Jerrycyx發表於2024-11-08

Preface

重點策略:

\[\large\textbf{\underline{先寫簡單好寫的演算法,再逐步修改最佳化}} \]

十分有效,百試百靈,屢試不爽。

A. Binary Imbalance

當有相鄰兩字元不相等時,就可以不斷向中間插入 0

所以輸出 NO 當且字串全為 1

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

const int N=105;
int n;
char str[N];

bool check()
{
	for(int i=1;i<n;i++)
		if((str[i]-'0')^(str[i+1]-'0'))
			return true;
	if(str[1]=='0') return true;
	else return false;
}
int main()
{
	int T; scanf("%d",&T);
	while(T--)
	{
		scanf("%d%s",&n,str+1);
		printf("%s\n",check()?"YES":"NO");
		
	}
}

B. Getting Points

究極橙題。

做法有點像這篇題解,用的是 \(O(1)\) 的數學做法。但是如果讓我再來一次,我寧願用二分。

因為數學做法太容易掛了,而且腦子要燒爛,看下程式碼就知道了。

下次遇到這種題先打最不容易錯的,再逐步最佳化(這題甚至不用最佳化)。

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

long long n,p,l,t;

int main()
{
	int T; scanf("%d",&T);
	while(T--)
	{
		scanf("%lld%lld%lld%lld",&n,&p,&l,&t);
		long long week=ceil(n/7.0);
		if((week+1)/2*l+week*t>=p) printf("%lld\n",n-min((long long)ceil(1.0*p/(l+t*2)),week));
		else printf("%lld\n",n-(week+1)/2-(long long)ceil(1.0*(p-(week+1)/2*l+week*t)/l));
	}
	return 0;
}

C. Insert and Equalize

所選 \(x\)\(\gcd(a_1,a_2,\dots,a_n)\),排序後如果原序列是等差數列就把 \(a_{n+1}\) 放在開頭或末尾,否則在中間找一個值最大的空插進去。

最後序列要全部變為最大值,用最大值減每一個數再除以最大公約數就是每一次的操作次數,全部加起來即可。

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

const int N=2e5+5;
int n;
long long a[N];

int gcd(int x,int y){return y?gcd(y,x%y):x;}
int main()
{
	int T; scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
			scanf("%lld",&a[i]);
		if(n==1)
		{
			printf("1\n");
			continue;
		}
		sort(a+1,a+n+1);
		int d=a[2]-a[1];
		for(int i=2;i<n;i++)
			d=gcd(d,a[i+1]-a[i]);
		long long ans=0;
		for(int i=1;i<=n;i++)
			ans+=(a[n]-a[i])/d;
		bool is_full=true;
		for(int i=n;i>=2;i--)
			if(a[i]-a[i-1]!=d)
			{
				ans+=(a[n]-(a[i]-d))/d;
				is_full=false;
				break;
			}
		if(is_full) ans+=min((long long)(a[n]-(a[1]-d))/d,1ll*n*d);
		printf("%lld\n",ans);
	}
	return 0;
}

D. Robot Queries

這題做的挺順的,就是連著被卡空間又被卡時間有點不爽。

但是做這道題就是“先寫簡單好寫的寫法,再逐步最佳化”策略的典範,以後要多多按照這個策略做題。

我的洛谷題解

E. Collapsing Strings

看出來是字典樹,也有一些做法,但是實現比較複雜還容易錯,所以我用的是這篇題解的處理方法。

久了沒打字典樹都快忘了,這次正好複習一下。

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int N=1e6+5;
int n;
string str[N];
long long ans,sumlen;

namespace Trie{

int trie[N][30],idx;
int cnt[N],end[N];
void insert(string &s)
{
	int p=0;
	for(int i=0;i<(int)s.length();i++)
	{
		int num=s[i]-'a'+1;
		if(!trie[p][num]) trie[p][num]=++idx;
		p=trie[p][num];
		cnt[p]++;
	}
	end[p]++;
	return;
}
long long query(string &s)
{
	int p=0;
	long long res=1ll*s.length()*n+sumlen;
	for(int i=0;i<(int)s.length();i++)
	{
		int num=s[i]-'a'+1;
		if(trie[p][num])
		{
			p=trie[p][num];
			res-=2*cnt[p];
		}
		else break;
	}
	return res;
}

}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		cin>>str[i];
		sumlen+=str[i].length();
		Trie::insert(str[i]);
	}
	for(int i=1;i<=n;i++)
	{
		reverse(str[i].begin(),str[i].end());
		ans+=Trie::query(str[i]);
	}
	printf("%lld\n",ans);
	return 0;
}

相關文章