Codeforces Round #619 (Div. 2)

Codeforces Round #619 (Div. 2)

https://codeforces.com/contest/1301

A - Three Strings

思路:只要a[i],b[i]中的一个和c[i]相等,直接把另一个和c[i]换就好

#include
#define MAXN 105
using namespace std;
char a[MAXN],b[MAXN],c[MAXN];
int t;
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%s%s%s",a,b,c);
		int n = strlen(a);
		int flag = 1;
		for(int i = 0;i < n;++i)
		{
			if(a[i] == c[i] || b[i] == c[i]);
			else
			{
				flag = 0;
				break;
			}
		}
		if(flag)
			printf("YES\n");
			else
				printf("NO\n");
			}
			return 0;
		}

B - Motarack’s Birthday

思路:很明显只有-1 -1 -1 … x和x -1 -1 -1这两种情况的x要和赋的值k作差,故只要求出x的最大值和最小值然后取他们的中位数即可让差最小

#include
#define MAXN 100005
#define INF 0x3f3f3f3f
using namespace std;
int a[MAXN],n,t,minn,maxn;
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		for(int i = 1;i <= n;++i)
			scanf("%d",&a[i]);
		minn = INF,maxn = 0;
		int ans = 0;
		for(int i = 2;i <= n;++i)
		{
			if(a[i] != -1 && a[i-1] == -1)
			{
				minn = min(a[i],minn);
				maxn = max(a[i],maxn);
			}
			else if(a[i] == -1 && a[i-1] != -1)
			{
				minn = min(a[i-1],minn);
				maxn = max(a[i-1],maxn);
			}
			else
				ans = max(ans,abs(a[i]-a[i-1]));
		}
		int id = (minn + maxn) / 2;
		ans = max(ans,maxn-id);
		if(minn == INF)
			ans = id = 0;
		printf("%d %d\n",ans,id);
	}
	return 0;
}

C - Ayoub’s function

思路:逆向考虑,用总的方案数减去只有0的方案数即可,相当于将n-m个0分为m+1块,让所有块的方案数之和最小,假设第i块为xi个0,那么它的方案数为 x i ∗ ( x i − 1 ) / 2 x_i *(x_i-1)/2 xi(xi1)/2,总和为 ( ∑ i x i 2 − ∑ i x i ) / 2 (\sum_i{x_i}^2-\sum_ix_i)/2 (ixi2ixi)/2,而 ∑ i x i \sum_ix_i ixi为定值n-m,故只要让 ∑ i x i 2 \sum_i{x_i}^2 ixi2最小,很明显让 x i x_i xi平均分配最好

#include
#define ll long long
using namespace std;
int t;
ll n,m;
inline ll cal(ll x)
{
	return x * (x+1) / 2;
}
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%lld%lld",&n,&m);
		n -= m;
		ll k = n/(m+1),r = n % (m+1);
		ll ans = cal(n+m) - cal(k+1) * r - cal(k) *(m+1-r);
		printf("%lld\n",ans);
	}
	return 0;
}

D - Time to Run

思路:先构造一种跑满所有路径的方案:
首先(m-1,“R”)走到最右边,然后(m-1,“L”)回到第一列
之后每次先(1,“D”)往下走一格,再(m-1,“R”)走到最右边,再(m-1,“UDL”)走回第一列,以此往复走完最后一行
最后再(n-1,“U”)从最后一行回来
对于给定的k值,直接在走完k步时停下来即可

#include
using namespace std;
struct node
{
	int k;
	string s;
	node(){}
	node(int k,string s):k(k),s(s){}
};
vector ve;
int n,m,k;
inline void print()
{
	printf("YES\n%d\n",ve.size());
	for(int i = 0;i < ve.size();++i)
		cout << ve[i].k << " " << ve[i].s << "\n";
}
int main()
{
	while(~scanf("%d%d%d",&n,&m,&k))
	{
		ve.clear();
		swap(n,m);
		if(k < n)
		{
			ve.push_back(node(k,"R"));
			print();
			continue;
		}
		if(n != 1)
			ve.push_back(node(n-1,"R"));
		k -= n-1;
		if(k < n)
		{
			ve.push_back(node(k,"L"));
			print();
			continue;
		}
		if(n != 1)
			ve.push_back(node(n-1,"L"));
		k -= n-1;
		for(int i = 1;i < m;++i)
		{
			ve.push_back(node(1,"D")),--k;
			if(!k)
				break;
			if(k < n)
			{
				ve.push_back(node(k,"R"));
				k = 0;
				break;
			}
			if(n != 1)
				ve.push_back(node(n-1,"R"));
			k -= n-1;
			if(k <= 3*(n-1))
			{
				int tmp = k / 3;
				if(tmp)
					ve.push_back(node(tmp,"UDL"));
				k %= 3;
				if(k == 1)
					ve.push_back(node(1,"U"));
				else if(k == 2)
					ve.push_back(node(1,"UD"));
				k = 0;
				break;
			}
			if(n != 1)
				ve.push_back(node(n-1,"UDL"));
			k -= 3*(n-1);
		}
		if(!k)
		{
			print();
			continue;
		}
		if(k < m)
		{
			ve.push_back(node(k,"U"));
			print();
			continue;
		}
		if(m != 1)
		ve.push_back(node(m-1,"U"));
		k -= m-1;
		if(!k)
		{
			print();
			continue;
		}
		printf("NO\n");
	}
	return 0;
}

你可能感兴趣的:(CF)