2021年“图森未来杯”全国程序设计邀请赛 个人题解

2021年“图森未来杯”全国程序设计邀请赛 个人题解

C题 Countdown

题目大意:

\(2021.4.10\) 距离 \(2021.10.16\) 有几天

思路解析:

签到题,输出 \(189\)

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;

int main(){

	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);

	cout<<189<<endl;

}

K题 K-Primes

题目大意:

给出 \(l\)\(k\) ,问在 \([l,l+2k]\) 之间是否存在至少 \(k+1\) 个质数

思路解析:

我们会发现区间的长度为 \(2k\) ,而质数的分布是越来越稀疏的,所以如果范围大的话,区间中有一半以上的质数是不可能的,所以我们可以直接小范围暴力,大范围直接判断即可

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;

int primes[maxn];
bool st[maxn];
int cnt;

void get_primes(int n)
{
    for (int i = 2; i <= n; i ++ )
    {
        if (!st[i]) primes[cnt ++ ] = i;
        for (int j = 0; primes[j] <= n / i; j ++ )
        {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0) break;
        }
    }
}

int main(){

	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);

	ll l,k;
	cin>>l>>k;

	get_primes(10000);

	if(k<=1000){

		ll sum=0;

		for(int i=l;i<l+2*k;i++){
			if(!st[i])sum++;
		}

		if(sum>=k+1)cout<<"Yes"<<endl;
		else cout<<"No"<<endl;

	}
	else cout<<"No"<<endl;

}

I题 I Love You

题目大意:

字符串匹配,问 \(a\) 串能否通过删减字符成为 \(b\)

思路解析:

双指针即可

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;

int main(){

	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);

	string a,b;
	cin>>a>>b;

	int j=0;

	for(int i=0;i<a.size();i++){
		if(a[i]==b[j])j++;
	}

	if(j==b.size())cout<<"Yes"<<endl;
	else cout<<"No"<<endl;


}

E题 Edge Game

题目大意:

在一棵树上,给出两个起始点,轮流向相邻节点移动,谁先吃掉对方棋子就赢,都以最优策略移动,问先手是否会赢

思路解析:

显然最优策略一定是两点间树上最短路径,做一次 \(dfs\) ,判断奇偶即可

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int maxn=4e5+5;

int h[maxn],nex[maxn],e[maxn],id;
int ans;
int a,b;

void add(int x,int y){
    e[++id]=y;
    nex[id]=h[x];
    h[x]=id;
}

void dfs(int x,int fa,int dis){
    if(x==b){
        ans=dis;
        return ;
    }
    for(int i=h[x];i;i=nex[i]){
        int j=e[i];
        if(j==fa)continue;
        dfs(j,x,dis+1);
    }
}

int main(){
    
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);

    int n;
    cin>>n;

    for(int i=1;i<n;i++){
        int x,y;
        cin>>x>>y;
        add(x,y);
        add(y,x);
    }

    cin>>a>>b;

    dfs(a,0,0);

    if(ans%2==1)cout<<"Yes"<<endl;
    else cout<<"No"<<endl;

}

G题 Group QQ Speed

题目大意:

\(n\) 个玩家被分为 \(m\) 人一组,每位玩家可以 \(ban\) 一张地图,同一组玩家共用一张地图且不能是组内 \(ban\) 选的地图,问最少需要准备几张地图, \(m\) 可以被 \(n\) 整除

思路解析:

很直观的考虑三种情况:

  • \(m=n\) 至少需要 \(2\) 张地图
  • \(m=1\) 至少需要 \(n+1\) 张地图
  • 除以上两种情况外,至少需要 \(3\) 张地图

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int maxn=1e5+5;

int main(){
    
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);

    int t;
    cin>>t;
    while(t--){

        ll n,m;
        cin>>n>>m;

        if(m==1)cout<<n+1<<endl;
        else if(n==m)cout<<2<<endl;
        else cout<<3<<endl;
        
    }

}

D题 Divide

题目大意:

给出 \(l_1,r_1,l_2,r_2\) ,令 \(a= \prod_{i=l_1}^{r_1}\) , \(b= \prod_{i=l_2}^{r_2}\) ,问 \(a\) 能否被 \(b\) 整除

思路解析:

根据唯一分解定理,我们可以把一个数分解成多个质数的幂乘积的形式,所以我们可以考虑对于a和b,我们枚举他们的每个质数因子,如果a的某个因子数量大于b的因子数量,那么他就一定不可被整除

所以我们就只需求出 \((l_1-1)! , r_1!, (l_2-1)! , r_2!\) ,用前缀和思想判断是否大于即可

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int maxn=1e7+5;

int primes[maxn];
int cnt;
int st[maxn];

void get_primes(int n) 
{
    for (int i = 2; i <= n; i ++ )
    {
        if (!st[i]) primes[cnt ++ ] = i;
        for (int j = 0; primes[j] <= n / i; j ++ )
        {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0) break;
        }
    }
}

int solve(int n, int p){
    int ans = 0;
    while(n){
        ans += n / p;
        n /= p;
    }
    return ans;
}

int main(){
    
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);

    get_primes(1e7+5);

    int t;
    cin>>t;
    while(t--){

        int ok=0;

        int a,b,c,d;
        cin>>a>>b>>c>>d;

        for(int i=0;i<cnt;i++){

            int A=solve(a-1,primes[i]);
            int B=solve(b,primes[i]);
            int C=solve(c-1,primes[i]);
            int D=solve(d,primes[i]);

            if(B-A>D-C){
                ok=1;
                break;
            }

        }
        
        if(ok==0)cout<<"Yes"<<endl;
        else cout<<"No"<<endl;

    }

}

推广一波小飞龙博客:戳这里@不会飞的小飞龙

posted @ 2021-09-01 19:28  不会飞的小飞龙  阅读(289)  评论(0编辑  收藏  举报
Live2D