2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题2题

Posted 小哈里

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题2题相关的知识,希望对你有一定的参考价值。

Solved Pro.ID Title Ratio(Accepted / Submitted)
1001 Yes, Prime Minister 17.07%(753/4410)(打表找规律)
1002 Might and Magic 11.59%(8/69)
1003 0 tree 15.19%(24/158)
1004 Decomposition 7.56%(62/820)
1005 Median 10.74%(417/3882)(贪心猜结论)
1006 The Struggle 0.00%(0/15)
1007 Power Station of Art 24.04%(25/104)
1008 Command and Conquer: Red Alert 2 4.88%(2/41)
1009 Typing Contest 4.27%(5/117)
1010 Array 3.83%(7/183)
1011 Game 26.92%(7/26)

1001 Yes, Prime Minister

题意:

  • 给出一个x,找出一段满足l<=x<=r,且l+(l+1)+…+r是一个质数时最短区间,输出长度,不存在输出-1。

思路:

  • 打表找规律,发现长度都是单个或相邻相加为素数,然后直接暴力枚举最近的几个数。
#include<bits/stdc++.h>
typedef long long LL;
using namespace std;
const int maxn = 2e7+1000;

//线性筛
int vis[maxn], primes[maxn], cnt;
void get_primes(int n){
    vis[0]=vis[1]=1;
    for(int i = 2; i < n; i++){
        if(!vis[i])primes[++cnt]=i;
        for(int j = 1; primes[j] <= n/i; j++){
            vis[primes[j]*i] = 1;
            if(i%primes[j]==0)break;
        }
    }
}

//打表找规律
int x;
bool check(int len){ //判断x时长度len是否满足
	for(int l = x-(len-1); l <= x; l++){
		int r = l+len-1;
		int sum = (l+r)*(r-l+1)/2;
		if(sum<0||sum>maxn)continue;
		if(!vis[sum]){
			if(len!=1&&len!=2)cout<<x<<":"<<len<<" "<<l<<" "<<r<<" "<<sum<<"\\n";
			return true;
		}
	}
	return false;
}


int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    get_primes(maxn-10);
    
    int T;  cin>>T;
    while(T--){
        cin>>x;
        if(x>0 && !vis[x]){cout<<1<<"\\n";continue;}
        if(x>0 && !vis[x+x+1]){cout<<2<<"\\n";continue;}
        if(x>0 && !vis[x+x-1]){cout<<2<<"\\n";continue;}
        if(x<0)x=-x;
        for(int i = x+1; ;i++){
            if(!vis[i]){cout<<(i-1)*2+2<<"\\n";break;}
            else if(!vis[i+i+1]){cout<<(i-1)*2+3<<"\\n"; break;}
        }
    }
    return 0;
}

1005 Median

题意:

  • 将1-n的n个整数分成m个集合,满足第i个集合的中位数是bi,求是否存在解。中位数定义为c[(k+1)/2]

思路:

  • 显然b数组的m个数放在m个不同的集合,剩下的n-m个数要放到这m个集合中且不影响原本的中位数。比如对于样例n=6,m=2,b=[3,5],集合被分为[1,2],[4],[6]三段。且任意两段中的任意一对数字可以被配对消掉以及最后剩下的数字一定是同一段内的
  • 如果如果 长度最大的段的数字个数mx <= 其他段数之和sum,那么最终要么全部消掉,要么只剩一个,这一个可以放到最左边或者最右边,所以直接YES。 反之如果mx > sum,那么这一段最后会剩下数字,此时当且仅当这一段左边的集合个数(中位数小于这一段),不小于这一段剩下的数字个数时(把剩下的数字分别放到那几个集合的右边,利用1234, 2也是中位数这个性质)为YES,否则NO。
#include<bits/stdc++.h>
using namespace std;
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T;  cin>>T;
	while(T--){
		int n,m;  cin>>n>>m;
		vector<int>a(n+2); a[n+1]=1;
		for(int i=1; i<=m; i++){
			int x;  cin>>x;  a[x]=1;
		}
		vector<pair<int,int> >vc;
		int len=0, cnt=0, sum=0;
		for(int i = 1; i <= n+1; i++){
			if(a[i]==1){
				if(len!=0){vc.push_back(make_pair(len,cnt)); sum+=len;}
				len=0; cnt++;
			}else{
				len++;
			}
		}
		if(n==m){cout<<"YES\\n"; continue;}
		sort(vc.begin(),vc.end());
		int mx = vc.back().first, x = vc.back().second;
		if(sum-mx>=mx ||(sum-mx<mx &&x>=mx-(sum-mx)))cout<<"YES\\n";
		else cout<<"NO\\n";
	}
    return 0;
}


以上是关于2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题2题的主要内容,如果未能解决你的问题,请参考以下文章

2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题4题

2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题5题

2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题5题

2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题2题

2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题5题

2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题4题