Educational Codeforces Round 84 (Rated for Div. 2) 题解

题目链接

A.Sum of Odd Integers

题目大意:给你两个正整数n和k。让你判断能否找到k个不同的正奇数使得它们的和为n。
题解:容易得出k各不同的正奇数之和至少为 k ∗ k k*k kk(即1,3,5…2k-1),所以n必须满足 n > = k ∗ k n>=k*k n>=kk。然后k个奇数之和奇偶性是确定的,还要满足 n n n% 2 = = k 2==k 2==k% 2 2 2(注意 k ∗ k k*k kk会爆 i n t int int)。

#include
using namespace std;
#define IOS std::ios::sync_with_stdio(false)
typedef long long ll;
const int maxn=1e5+5;
const int mod=1e9+7;
 
void solve()
{
ll n,k;
scanf("%lld %lld",&n,&k);
if(n>=k*k&&(n-k*k)%2==0)
	printf("YES\n");
else printf("NO\n");
}
int main()
{
	int t;scanf("%d",&t);while(t--)
	solve();
	return 0;
}

B.Princesses and Princes

题目大意:有 n n n个公主和 n n n个王子,编号都为 1 1 1~ n n n。每个公主都只愿意和部分王子结婚,并且她们会优先选择编号较小的王子,每个王子只能被选择一次。我们会让编号较小的公主开始先做选择,知道所有公主选择完毕。但是这样可能会导致剩下一些公主和王子没配对,这时候你作为国王可以让一个公主再爱上一个王子,尽可能多的增加配对数。
题解:先看一下能不能完全匹配,如果不能,在没有匹配当中任意输出一个公主和王子就好了,保证能多增加一对。

#include
using namespace std;
#define IOS std::ios::sync_with_stdio(false)
typedef long long ll;
const int maxn=1e5+5;
const int mod=1e9+7;
 
vector<int> v[maxn];
set<int> si;
void solve()
{
int n;
scanf("%d",&n);
si.clear();
for(int i=1;i<=n;i++)
	v[i].clear();
for(int i=1;i<=n;i++)
{
	int k;
	scanf("%d",&k);
	for(int j=1;j<=k;j++)
	{
		int temp;
		scanf("%d",&temp);
		v[i].push_back(temp);
	}
}
int ans1=0,ans2=0;
for(int i=1;i<=n;i++)
{
	int j;
	for(j=0;j<v[i].size();j++)
	{
		if(!si.count(v[i][j]))
		{
			si.insert(v[i][j]);
			break;
		}
	}
    if(j==v[i].size()&&!ans1)
      ans1=i;
}
if(!ans1)
printf("OPTIMAL\n");
else {
	printf("IMPROVE\n");
	for(int i=1;i<=n;i++)
		if(!si.count(i))
		{
			ans2=i;
			break;
		}
	printf("%d %d\n",ans1,ans2);
}
}
int main()
{
	int t;scanf("%d",&t);while(t--)
	solve();
	return 0;
}

C.Game with Chips

题目大意:在一个 n ∗ m n*m nm的网格中有k个碎片,给你每一个碎片的起点坐标以及他们需要到达的终点坐标。你有四种操作,分别是将所有碎片向上、向下、向左、向右移动一个单位(但不能超出边界)。要求你给出一种操作方案使的每一个碎片到达过自己所对应的终点,且要求操作数不能超过 2 m n 2mn 2mn
题解:这道题目看上去很难,好像要没一个碎片单独考虑。然而其实你只要先把所有碎片汇集到同一个格子比如左上角(做多需要 n + m − 2 n+m-2 n+m2步操作),然后你就可以让所有碎片一起动,遍历完所有方格就好了。总共需要 m n + m + n − 3 mn+m+n-3 mn+m+n3步操作,肯定是比题目所要求的 2 m n 2mn 2mn要小的。

#include
using namespace std;
#define IOS std::ios::sync_with_stdio(false)
typedef long long ll;
const int maxn=1e5+5;
const int mod=1e9+7;
 
void solve()
{
int n,m,k;
scanf("%d %d %d",&n,&m,&k);
int x,y;
for(int i=1;i<=k;i++)
scanf("%d %d",&x,&y);
for(int i=1;i<=k;i++)
scanf("%d %d",&x,&y);
printf("%d\n",m*n+m+n-3);
for(int i=1;i<=m-1;i++)
	printf("L");
for(int i=1;i<=n-1;i++)
	printf("U");
for(int i=1;i<=m;i++)
{
	if(i&1)
	for(int i=1;i<=n-1;i++)
		printf("D");
	else 
	for(int i=1;i<=n-1;i++)
		printf("U");
	if(i!=m)
	printf("R");
    else printf("\n");
}
}
int main()
{
	//int t;scanf("%d",&t);while(t--)
	solve();
	return 0;
}

D.Infinite Path

没做出来

E.Count The Blocks

题目大意:有一串整数,从 0 0 0 1 0 n − 1 10^n-1 10n1。如果该数不足n位的则在其前面用0补足。长度为L的块的定义为在一个数中连续L位数字为相同的数字,且不能向左右扩展(这一段左右没有数字或数字不同)。让你分别求出长度为1到长度为n的块的数目,答案对 998244353 998244353 998244353取余。
题解:首先长度为n的块的数目很好求,很明显是 10 10 10。然后从后往前推你就会发现能推出公式。 a n s = 10 ∗ 9 ∗ 2 ∗ 1 0 ( n − i − 1 ) + 9 ∗ 9 ∗ ( n − i − 1 ) ∗ 1 0 ( n − i − 2 ) ans=10*9*2*10^{(n-i-1)}+9*9*(n-i-1)*10^{(n-i-2)} ans=109210ni1)+99ni110(ni2)(i=n和i=n-1时候需要特殊判断)。

#include
using namespace std;
#define IOS std::ios::sync_with_stdio(false)
typedef long long ll;
const int maxn=1e5+5;
const int mod=998244353;
 
ll pow_bound(ll a,ll k)
{
	if(k==0)
		return 1;
	ll temp=pow_bound(a,k/2);
	ll ans=temp*temp%mod;
	if(k&1)
		ans=ans*a%mod;
	return ans;
}
 
void solve()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
	if(i==n)
	{
		printf("10\n");
		continue;
	}
	if(i==n-1)
	{
		printf("180 ");
		continue;
	}
	ll ans=0;
	ans+=10*9*2*pow_bound(10,n-i-1);
	ans%=mod;
	ans+=10*9*9*(n-i-1)*pow_bound(10,n-i-2);
    ans%=mod;
    printf("%lld",ans);
    if(i==n)
    	printf("\n");
    else printf(" ");
}
}
int main()
{
	//int t;scanf("%d",&t);while(t--)
	solve();
	return 0;
}

刚开始写这种题解,水平能力也有限,大家要是有什么意见或建议可以写在评论区,估计看的人都没有吧

你可能感兴趣的:(codeforces)