Codeforces Round #690 (Div. 3)

A:水题,根据题目意思模拟即可
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int st[10005],prime[10005],cnt;
int vis[105];
int a[305];
void ola()
{
	for(int i=2;i<=1000000;i++)
	{
		if(st[i]==0) prime[cnt++]=i;
		for(int j=0;j<=cnt&&j*prime[i]<=1000000;j++)
		{
			st[i*prime[j]]=1;
			if(i%prime[j]==0) break;
		}
	}
}
ll gcd(ll a,ll b)
{
	return b==0?a:gcd(b,a%b);
}
ll qpow(ll a,ll b,ll mod)
{
	ll ans=1;
	while(b)
	{
		if(b&1) ans=ans*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return ans % mod; 
}
int main()
{
	ios::sync_with_stdio;
	cin.tie(0);cout.tie(0);
	int t; cin >> t;
	while(t--)
	{
		int n; cin >> n;
		memset(a,0,sizeof(a));
		for(int i=1;i<=n;i++) cin >> a[i];
		int k=n;
		int cnt=1;
		int tmp=1;
		while(tmp<=n)
		{
			if(tmp%2) cout << a[cnt++] <<" ";
			else cout << a[k--] << " "; 
			tmp++;
		}
		cout << endl;
	}
	return 0;
 } 
B:删除一段连续字符判断剩下的是否是“2020”,YES就6种情况
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int st[10005],prime[10005],cnt;
int vis[105];
int a[305];
void ola()
{
	for(int i=2;i<=1000000;i++)
	{
		if(st[i]==0) prime[cnt++]=i;
		for(int j=0;j<=cnt&&j*prime[i]<=1000000;j++)
		{
			st[i*prime[j]]=1;
			if(i%prime[j]==0) break;
		}
	}
}
ll gcd(ll a,ll b)
{
	return b==0?a:gcd(b,a%b);
}
ll qpow(ll a,ll b,ll mod)
{
	ll ans=1;
	while(b)
	{
		if(b&1) ans=ans*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return ans % mod; 
}
int main()
{
	ios::sync_with_stdio;
	cin.tie(0);cout.tie(0);
	int t; cin >> t;
	while(t--)
	{
		int n; cin >> n;
		string s; cin >> s;
		if (s == "2020" ||(s[0]=='2'&&s[1]=='0'&&s[2]=='2'&&s[3]=='0')||(s[0] == '2' && s[n - 1] == '0' && s[n - 2] == '2' && s[n - 3] == '0') ||(s[0] == '2' && s[1] == '0' && s[n - 2] == '2' && s[n - 1] == '0') ||(s[0] == '2' && s[1] == '0' && s[2] == '2' && s[n - 1] == '0')||(s[n-1]=='0'&&s[n-2]=='2'&&s[n-3]=='0'&&s[n-4]=='2'))	cout << "YES" << endl;
		else cout << "NO" << endl;
	}
	return 0;
 } 
C:输入一个数X,问x最小能用哪个数上的每位数之和(每位数不相同)表示,如果没有这样的数输出-1. 如果x大于45直接输出-1,优先取0~9中大的数这样保证数的位数最小,然后排序输出
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int st[10005],prime[10005],cnt;
int vis[105];
int a[305];
void ola()
{
	for(int i=2;i<=1000000;i++)
	{
		if(st[i]==0) prime[cnt++]=i;
		for(int j=0;j<=cnt&&j*prime[i]<=1000000;j++)
		{
			st[i*prime[j]]=1;
			if(i%prime[j]==0) break;
		}
	}
}
ll gcd(ll a,ll b)
{
	return b==0?a:gcd(b,a%b);
}
ll qpow(ll a,ll b,ll mod)
{
	ll ans=1;
	while(b)
	{
		if(b&1) ans=ans*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return ans % mod; 
}
int main()
{
	ios::sync_with_stdio;
	cin.tie(0);cout.tie(0);
	int t; cin >> t;
	while(t--)
	{
		int x; cin >> x;
		vector<int>v;
		int cnt=9;
		while (x >= 10&&cnt)
		{
			v.push_back(cnt);
			x -= cnt--;
		}
		if(x>45) cout << -1 << endl;
		else if(x)
		{
			int tmp=(1+cnt)*cnt/2;
			if (x>tmp)	cout << -1 << endl;
			else
			{
				int temp=cnt;
				while(x != 0)
				{
					if (x >= temp)	v.push_back(temp), x -= temp;
					temp--;
				}
				sort(v.begin(), v.end());
				vector<int>::iterator it = v.begin();
				for(; it != v.end(); ++it)
				{
					cout<<(*it);
				}
				cout << endl;
			}
		}
	}
	return 0;
 } 
D:一个数组,每次能让ai加到a(i+1)或者a(i-1),问最少多少次让数组中元素都相等。最后数组元素之和sum肯定不变,且每个元素都是sum的因子,那筛出sum的所有因子,从小到大模拟一遍即可。
#include <iostream>
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
int st[10005],prime[10005],cnt;
int vis[105];
ll a[3005];
void ola()
{
	for(int i=2;i<=1000000;i++)
	{
		if(st[i]==0) prime[cnt++]=i;
		for(int j=0;j<=cnt&&j*prime[i]<=1000000;j++)
		{
			st[i*prime[j]]=1;
			if(i%prime[j]==0) break;
		}
	}
}
ll gcd(ll a,ll b)
{
	return b==0?a:gcd(b,a%b);
}
ll qpow(ll a,ll b,ll mod)
{
	ll ans=1;
	while(b)
	{
		if(b&1) ans=ans*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return ans % mod; 
}
int main()
{
	ios::sync_with_stdio;
	cin.tie(0);cout.tie(0);
    ll t;
    cin >> t;
    while (t--)
    {
        ll n;
        cin >> n;
        memset(a,0,sizeof(a));
        ll sum=0;
        for (ll i = 1; i <= n; i++)
        {
            cin >> a[i];
            sum+=a[i];
        }
        vector<ll>v;
        for(ll i=1;i*i<=sum;i++)
        {
        	if(sum%i==0) 
			{
				v.push_back(i);
				if(i*i!=sum) v.push_back(sum/i);
			}
        	
		}
		sort(v.begin(),v.end());
		ll flag1=1,flag2=0;
		for(ll i=0;i<v.size();i++)
		{
			ll summ=0;
			flag1=1;
			for(ll j=1;j<=n;j++)
			{
				summ+=a[j];
				if(summ==v[i]) summ=0;
				if(summ>v[i]) 
				{
					flag1=0;
					break;
				}
			}
			if(flag1)
			{
				cout << n-sum/v[i] << endl;
				flag2=1;
				break;
			}
		}
		if(flag2==0) cout << n-1 << endl;
    }
    return 0;
}
E1:从n各数中选三个数,保证三个数中最大值减最小值小于等于2。排序+lower_bound。从第三个数开始遍历,每次去找比这个数小2的数,得到位置,即可通过组合数算出。
别用memset初始化,开始没注意,一直tle9,删了秒过
#include <iostream>
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
int st[10005],prime[10005],cnt;
int vis[105];
ll a[200005];
void ola()
{
	for(int i=2;i<=1000000;i++)
	{
		if(st[i]==0) prime[cnt++]=i;
		for(int j=0;j<=cnt&&j*prime[i]<=1000000;j++)
		{
			st[i*prime[j]]=1;
			if(i%prime[j]==0) break;
		}
	}
}
ll gcd(ll a,ll b)
{
	return b==0?a:gcd(b,a%b);
}
ll qpow(ll a,ll b,ll mod)
{
	ll ans=1;
	while(b)
	{
		if(b&1) ans=ans*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return ans % mod; 
}
int main()
{
	ios::sync_with_stdio;
	cin.tie(0);cout.tie(0);
    int t; cin >> t;
    while(t--)
    {
    	ll n; cin >> n;
    	for(ll i=1;i<=n;i++) cin >> a[i];
    	sort(a+1,a+1+n);
    	ll ans=0;
    	for(ll i=3;i<=n;i++)
    	{
    		ll pos=lower_bound(a+1,a+1+n,a[i]-2)-a;
    		ll t=i-pos;
    		if(t<2) continue;
    		else 
    		{
    			ans+=(t-1)*(t)/2;
			}
		}
    	cout << ans << endl;
	}
    return 0;
}
要下课了,剩下E2和F抽时间再写吧
2020/12/21 
E2 题目意思和E1一样就是没限定m和k,再加个取模。费马小定理求逆元+组合数,也可以用lucas。
#include <iostream>
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define MOD 1000000007
using namespace std;
typedef long long ll;
int st[10005],prime[10005],cnt;
int vis[105];
ll a[200005];
ll fac[200005],inv[200005];
void ola()
{
	for(int i=2;i<=1000000;i++)
	{
		if(st[i]==0) prime[cnt++]=i;
		for(int j=0;j<=cnt&&j*prime[i]<=1000000;j++)
		{
			st[i*prime[j]]=1;
			if(i%prime[j]==0) break;
		}
	}
}
ll gcd(ll a,ll b)
{
	return b==0?a:gcd(b,a%b);
}
ll qpow(ll a,ll b)
{
	ll ans=1;
	while(b)
	{
		if(b&1) ans=ans*a%MOD;
		a=a*a%MOD;
		b>>=1;
	}
	return ans % MOD; 
}
void init()
{
	fac[0]=inv[0]=1;
	for(int i=1;i<200005;i++)
	{
		fac[i]=(fac[i-1]*i)%MOD;//求阶乘
		inv[i]=qpow(fac[i],MOD-2);//费马小定理求逆元
	}
}
ll C(ll a,ll b)
{
	if(a<b||b<0) return 0;
	return (fac[a]*inv[b]%MOD)*inv[a-b]%MOD;
}
int main()
{
	ios::sync_with_stdio;
	cin.tie(0);cout.tie(0);
    int t; cin >> t;
    init();
    while(t--)
    {
    	int n,m,k; cin >> n >> m >> k;
		for(int i=1;i<=n;i++) cin >> a[i];
		sort(a+1,a+1+n);
		ll ans=0;
		int l=1;	
		for(int r=m;r<=n;r++)
		{
			while(a[r]-a[l]>k) l++;//a[l]太小
			if(r-l+1<m) continue;//不够m个数
			ans=(ans+C(r-l,m-1))%MOD;//确定当前最大值为a[r],再从剩下的[l,r-1](即r-1-l+1=r-l)取m-1个数
		}
		 cout << ans << endl; 
	}
    return 0;
}
F:给你n个二元组,代表线段的左右端点,问最少删几条线段,使得剩下当中存在一个线段与所有剩下的所有线段都有交集。最多删除n-1次,我们要删除的线段是它的右端点比当前该线段左端点小,左端点比当前线段右端点大。二分左端点和右端点。每次比较取最小值即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 10005;
const int N = 200005;
int st[MAXN+5],prime[MAXN+5],cnt;

/*void ola()
{
	for(int i=2;i<=MAXN;i++)
	{
		if(!st[i]) prime[cnt++];
		for(int j=0;j<=cnt&&i*prime[j]<=MAXN;j++)
		{
			st[i*prime[j]]=1;
			if(i%prime[j]) break;
		}
	}
}
ll gcd(ll a, ll b)
{
	return b==0?a:gcd(b,a%b);
}*/
pair<int,int>p[N];
int ls[N],rs[N];
int main()
{
	//ios::sync_with_stdio;
	//cin.tie(0);cout.tie(0);
	int t; cin >> t;
	while(t--)
	{
		int n; cin >> n;
		
		
		for(int i=1;i<=n;i++)
		{
			int l,r; cin >> l >> r;
			p[i]=make_pair(l,r);
			ls[i]=l; rs[i]=r;
		}
		sort(ls+1,ls+1+n);
		sort(rs+1,rs+1+n);
		ll ans = n-1;
		for(int i=1;i<=n;i++)
		{
			ll dl=lower_bound(rs+1,rs+1+n,p[i].first)-rs-1;
			ll dr=ls+n+1-upper_bound(ls+1,ls+1+n,p[i].second);
			ans = min(ans, dl+dr);
		}
		cout << ans << endl;
	}
	return 0;
}




全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务