Educational Codeforces Round 84 (Rated for Div. 2)

个人博客:voids5.cn

A. Sum of Odd Integers

题意:两个数n、k,判断n是否能被产分成k个不同的素数

解题思路:首先n,k奇偶性要相同,然后根据求和公式k个奇数相加最小数为k2,故n>=k2

Code:

#include

using namespace std;
typedef long long ll;
ll t,n,k; //注意范围

int main(){
	cin>>t;
	while(t--){
		cin>>n>>k;
		if(n%2 == k%2 && n>=k*k){
			puts("YES");
		}
		else {
			puts("NO");
		}
	}

	return 0;
}

B. Princesses and Princes

题意:有n个公主每人都有个名单,每个公主依次从名单上找到数最小并且未被选走的王子,如果最后公主有剩余则在某个公主的名单上添加一个未被选走的王子

解题思路:对已选走的王子及剩余的公主都进行标记,然后搭配即可

Code:

#include

using namespace std;
typedef long long ll;
const int N = 1e5+5,mod=998244353;
vector<int>ve[N];
int t,n,vis[N];

int main(){
	cin>>t;
	while(t--){
		cin>>n;
//		vectorve[N];
		for(int i=1;i<=n;i++){
			ve[i].clear();
			int k;
			cin>>k;
			for(int j=1;j<=k;j++){
				int x;
				cin>>x;
				ve[i].push_back(x);
			}
		}
		memset(vis,0,sizeof(vis));
		int temp=-1,flag=0;
		for(int i=1;i<=n;i++){
			flag=0;
			for(int j=0;j<ve[i].size();j++){
				if(!vis[ve[i][j]]){
					flag=1;
					vis[ve[i][j]]=1;
					break;
				}
			}
			if(!flag){
				temp=i;
			}
		}
		if(temp==-1){
			cout<<"OPTIMAL"<<endl;
		}
		else {
			for(int i=1;i<=n;i++){
				if(!vis[i]){
					cout<<"IMPROVE"<<endl;
					cout<<temp<<' '<<i<<endl;
					break;
				}
			}
		}
	}

	return 0;
}

C. Game with Chips

题目链接:https://codeforces.com/contest/1327/problem/C

题目大意:n*m方格中有k个卡牌,每个卡牌有初始位置及需要经过一次的位置,如果能到达则给出路径,否则输出-1,每次移动所有卡牌都要移动,到边界位置后卡牌不再移动

解题思路:先将卡牌一道到(1,1)位置,然后按行小优先原则依次移动,考虑最坏情况移动次数为2*(n-1)(m-1)<2n*m;

Code:

#include
using namespace std;
typedef long long ll;
const int N=500;
int t,n,m,k;
string s;
struct node
{
	int x,y;
}eg[N];
bool cmp(node a,node b)
{
	if (a.x==b.x)
		return a.y<b.y;
	else return a.x<b.x;
}
int main()
{
	cin>>n>>m>>k;
	for(int i=1;i<m;i++) s.push_back('L');
	for(int i=1;i<n;i++) s.push_back('U');
	int x,y;
	for(int i=0;i<k;i++) cin>>x>>y;

	for(int i=1;i<=k;i++)
	{
		cin>>eg[i].x>>eg[i].y;
	}
	eg[0]={1,1};
	sort(eg,eg+k+1,cmp);
	for(int i=1;i<=k;i++)
	{
		int num1=abs(eg[i].x-eg[i-1].x);
		int num2=abs(eg[i].y-eg[i-1].y);
		if(eg[i].x>=eg[i-1].x)
		{
			for(int j=0;j<num1;j++)
				s.push_back('D');
		}
		else
		{
			for(int j=0;j<num1;j++)
				s.push_back('U');
		}
		if(eg[i].y>=eg[i-1].y)
		{
			for(int j=0;j<num2;j++)
				s.push_back('R');
		}
		else
		{
			for(int j=0;j<num2;j++)
				s.push_back('L');
		}
	}
	if(s.size()<=2*n*m){
		cout<<s.size()<<endl<<s;
	}
	else cout<<"-1"<<endl;

	return 0;
  }
 

E. Count The Blocks

链接:https://codeforces.com/contest/1327/problem/E

题意:求0 ~ 10^n - 1中数目为1~n的块数

思路:假设num为i长度的块 1.num位于中间,放的方法有(n-i-1)种,则num前后的数都与num不同,都有9种可能,剩下的(n-i-2)个位置都有10种可能,num本身有10种
2.num位于边界,num前或后的数放的方法有9种,剩下的(n-i-1)都有10种可能,num本身10种可能
3.num长为1,只有一种方法,本身10种可能

Code:


#include

using namespace std;
typedef long long ll;
const int N = 100,mod=998244353;
int n;

ll ksm(ll a,ll b){
	ll res=1;
	while(b>0){ //注意b可能小于0
		if(b&1) res=res*a%mod;
		b>>=1;
		a=a*a%mod;
	}
	return res;
}

int main(){
	cin>>n;
	for(ll i=1;i<n;i++){
		ll sum=0;
		sum=(sum+(n-i-1)*9*9*10*ksm(10,n-i-2))%mod;//中间情况
		sum=(sum+2*9*ksm(10,n-i-1)*10)%mod;//边界情况
		cout<<sum<<" ";
	}
	cout<<10<<endl;

	return 0;
}

剩下的都是有生之年系列

你可能感兴趣的:(CF)