Codeforces Round #659 (Div. 2) A~C

目录

A - Common Prefixes

B1 - Koa and the Beach (Easy Version)

B2. Koa and the Beach (Hard Version)

C - String Transformation 1


补了这一场,感觉真心难,菜鸡呻吟~

A - Common Prefixes

 思路就是把初始字符串初始化为:‘aaaaaaaaaaaaaaaaaaaaaaaaa’。对于第i个数代表着字符串  s_i 和字符串s_{i+1} 的公共前缀长度为x;所以只需要在把s_i的字符的第x+1个字符改变即可;后面以此类推;

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+7;

int a[N];
int main()
{
	int t;
	cin >>t;
	while(t--)
	{
		string s="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
		
		int n;
		cin >>n;
		cout <<s<<endl;
		for(int i=0;i<n;i++)
		{
			int x;
			cin >>x;
			s[x]=s[x]=='a'?'b':'a';
			cout <<s<<endl;
		}
	}
}

B1 - Koa and the Beach (Easy Version)

题意: 有 n 片海域,每片海域有一个初始深度,每 2 * k秒,前 k秒 每秒深度 +1 ,后 k 秒每秒深度 -1 .有一个人想从海岸一边游到另一边 ,每秒它可以移动到下一片海域或者停留在当前海域,如果当前海域深度大于 l 他会被淹死,问他可不可以游到对岸。

 Easy Version数据范围很小,可以用DP来做;

  • f(i,j) 表示 游到第i片海域,时间是第j秒的状态是否合法;
  • 状态转移:f[i][j] = f[i][j-1] || f[i-1][j-1]   表示上一秒它可以在这个海域没动或者是从上个海域转移过来的;只要两个状态有一个符合条件即可
  • 注意判断f[i][j]本身状态是否合法
#include <bits/stdc++.h> 
using namespace std;
const int N=210;
int f[N][N*100],d[N],n,k,l,p[N*100];
int main()
{
	int t;cin >>t;
	while(t--)
	{
		memset(f,0,sizeof f);
		cin >>n>>k>>l;
		for(int i=1;i<=n;i++) cin >>d[i];
		for(int i=0;i<k*2;i++) p[i]=i<=k?i:2*k-i,f[0][i]=1;
		for(int i=1;i<=n;i++)
		{
			for(int j=0;j<2*k*n;j++)
			{
				f[i][j]=f[i][j-1]||f[i-1][j-1];
				if(l<p[j%(2*k)]+d[i]) f[i][j]=0;
			}
		}
		int flag=0;
		for(int i=0;i<2*k*n;i++) if(f[n][i]) {flag=1;break;}
		if(flag) puts("Yes");
		else puts("No");
	}
}

B2. Koa and the Beach (Hard Version)

待补 

C - String Transformation 1

题意:给你两个长度相同的字符串a,b。你每次可以选择a中一些有相同字符的位置,把这些字符改成另一个字符(注意:修改后的字符一定要大于修改前的)。问至少要经过多少次修改,才能使a变成b。

思路:贪心

首先只要存在 a[i] > b[i] 就直接pass;

贪心策略:我们可以记录下a中的每种字符最后分别要修改成哪几种字符。
但每次只是将这个字符修改为要修改成的几种字符中最小的。
例如:aab->bcc中,a就要修改为b和c两种字符
但我们把所有a修改成b,然后b就要修改成c这一种字符。一共是两次操作。

#include <bits/stdc++.h> 
using namespace std;
vector<int> v[26];
int main()
{
	int t;cin >>t;
	while(t--)
	{
		int n,f=0;
		for(int i=0;i<26;i++) v[i].clear();
		string a,b;cin >>n>>a>>b;
		for(int i=0;i<n;i++)
		{
			if(a[i]>b[i]){f=1;break;}
			else if(a[i]<b[i]) {v[a[i]-'a'].push_back(b[i]-'a');}
		}
		if(f) {puts("-1");continue;}
		int ans=0;
		for(int i=0;i<19;i++)
		{
			sort(v[i].begin(),v[i].end());
			v[i].erase(unique(v[i].begin(), v[i].end()), v[i].end());
			ans+=v[i].size()>0?1:0;
			for(int j=0;j<v[i].size();j++) if(v[i][j]!=v[i][0]) v[v[i][0]].push_back(v[i][j]);
		}
		cout <<ans<<endl;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值