Educational Codeforces Round 84

链接:http://codeforces.com/contest/1327
A 问k个不相同的正奇数相加是否等于n,k个奇数相加的奇偶性一定与k相同,而且k个不相同的正奇数最小等于k^2 (1+3+…+2*k-1)判断一下就可以了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
const int N=100010;
int main()
{
	ll t,n,k;//会爆int
	cin>>t;
	
	while(t--)
	{
		cin>>n>>k;
		if((((n&1)&&(k&1))||(n%2==0&&k%2==0))&&n>=k*k) cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	 } 
	return 0;
  }  

B 给n个公主找老公,模拟一遍就可以了,如果有公主没找到就再找任意一个没配对的王子就行了,样例n的总合不超过1e5不会超时

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
const int N=100010;
int t,n;
vector<int> g[N];
bool st[N];
int main()
{
	IOS;
	cin>>t;
	while(t--)
	{
		
		cin>>n;
		for(int i=1;i<=n;i++)
		{
			int k,x;
			cin>>k;
			for(int j=0;j<k;j++)
			{
				cin>>x;
				g[i].push_back(x);
			}
		}
		int l=-1;//标记没配对的公主
		memset(st,0,sizeof st);//标记王子
		for(int i=1;i<=n;i++)
		{
			bool flag=0;
			for(int j=0;j<g[i].size();j++)
				if(!st[g[i][j]])
				{
					flag=1;
					st[g[i][j]]=1;
					break;
				}
			if(!flag) l=i;
		 } 
		if(l==-1)
		{
			cout<<"OPTIMAL"<<endl;
		}
		else 
		{
			for(int i=1;i<=n;i++)
				if(!st[i])
				{
					cout<<"IMPROVE"<<endl<<l<<' '<<i<<endl;
					break;
				}
		}
		for(int i=1;i<=n;i++)
			g[i].clear();
	 } 
	return 0;
  }  

C 已知k个芯片的位置,每次将所有芯片向同一个方向移动(如过超出边界就不动)以格问是否可以让所有芯片都经过k个指定的位置,如果可以并且移动次数不超过2nm就输出移动的顺序(wtm看成了2纳米,???我就纳了闷了我是咋猪脑子嘛),否则输出-1
因为超出边界就不动,所以我们可以把所有芯片都移动到同一个位于边界位置,我是把他们都移动到点(1,1),假设位于对角的(n,m)有芯片就需要移动n-1+m-1次,不过(n,m)有没有这样移动都可以将他们全部移动到(1,1),就不判断了,而且移动方向与日常习惯不一样需要注意一下(血得教训啊),然后再从(1,1)向每一个指定位置移动就可以了,我排了个序,就会一行一行的移动,最坏情况是每一行的头尾都需要移动 2*(m-1)*(n-1)次,再加上开始的次数就是2nm-n-m-1,不会有-1的情况了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
const int N=1010;
int t,n,m,k;
int x[N],y[N];
string s;
struct node
{
	int x,y;
}e[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()
{
	IOS;
	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 l,r;
	for(int i=0;i<k;i++) cin>>l>>r;//芯片的位置没有用到
	e[0]={1,1};
	for(int i=1;i<=k;i++)
		cin>>e[i].x>>e[i].y;
	sort(e,e+k+1,cmp);
	for(int i=1;i<=k;i++)
	{
		l=abs(e[i].x-e[i-1].x);
		r=abs(e[i].y-e[i-1].y);//到下一个指定位置横纵坐标分别需要移动的次数
		if(e[i].x>=e[i-1].x)
		{
			for(int j=0;j<l;j++)
				s.push_back('D');
		}
		else 
		{
			for(int j=0;j<l;j++)
				s.push_back('U');
		}
		if(e[i].y>=e[i-1].y)
		{
			for(int j=0;j<r;j++)
				s.push_back('R');
		}
		else 
		{
			for(int j=0;j<r;j++)
				s.push_back('L');
		}
	}
	cout<<s.size()<<endl<<s;
	return 0;
  } 

D 不会,花了半小时看懂题意比赛也结束了,当时用的镜像网站看题没看过题人数,当个教训吧,一定要跟榜!!!其实看了e题当时大概率也是过不了hhh
E 统计0到10^n-1的块的个数(包括前导0)。
块的长度一定不超过n
先看n=1,1的个数就是10;
n=2,在n=1的基础上每个数前加一个相同的数,就是长度2的块了,所以长度2的块有10个,然后想0到99每个数有两位就需要2100个数字,块2(长度为2的块)有10个,消耗了210个数字,剩下了180个数字就都是块1了。
n=3,块3的个数和上面一样加一个相同的数还是有10个,刚好是n=2是块2的个数,这样可以发现一个规律,n时块i的个数等于n-1时i-1的个数(不会证明),这样可以求得块2到块n的个数,块1就和上面一样用总的出现的数字减块2到块n消耗的数字得到,一直向下推就可以了,

#include<iostream>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int N=200010;
ll n,a[N],sum[N],s[N];
ll ksm(ll a,ll b)
{
	ll res=1;
	while(b)
	{
		if(b&1) res=res*a%mod;
		b/=2;
		a=a*a%mod;
	}
	return res;
 } 
 int main()
 {
 	cin>>n;
 	a[1]=10;
 	sum[1]=s[1]=10;
 	for(int i=2;i<=n;i++)
 	{
 		sum[i-1]=(sum[i-1]+s[i-1])%mod; 
 		a[i]=(i*ksm(10,i)%mod-sum[i-1]+mod)%mod;
 		s[i]=(s[i-1]+a[i])%mod;
 		sum[i]=(sum[i-1]+a[i])%mod;
	}
	for(int i=n;i;i--)
		cout<<a[i]<<' ';
	return 0;
}
原文地址:https://www.cnblogs.com/neflibata/p/12871773.html