iwtgm-27

题目链接

A.

先把菜肴按取出时间从前到后排序,因为先拿出先熟的一定最优
去枚举什么时候取出第i道菜,限制是时间是在前一道菜取出的时间之后,三层循环的dp
不错的状态转移

int f[2*210][2*210];
int a[210];
void solve() {
    memset(f,0x3f3f3f3f,sizeof(f));
    for(int i=0;i<2*210;i++)f[0][i]=0;
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    sort(a+1,a+1+n);
    for(int i=1;i<=n;i++){
        for(int j=0;j<2*n;j++){
            for(int k=j+1;k<2*n;k++){
                f[i][k]=min(f[i][k],f[i-1][j]+abs(k-a[i]));
            }
        }
    }
    int ans=inf;
    for(int i=1;i<2*n;i++)ans=min(f[n][i],ans);
    cout<<ans<<endl;
}

B.

代码有注释

#include<bits/stdc++.h>

using namespace std;

const int maxn=3e5+5;
string s;

int A[maxn];//A[i]表示,s[i]左边有几个交替出现的字母,不包括自己
int B[maxn];//B[i]表示,s[i]右边有几个交替出现的字母,不包括自己
//对于每个点的ans至少等于1
//如果s[i]==L,则说明可以往左走,ans+=1+A[i]
//如果s[i+1]==R,则说明可以往右走,ans+=1+B[i+1]
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        cin>>s;
        s+='L';//把最后一个点的情况处理成不能往右走
        A[0]=0;
        for(int i=1;i<n;i++)
        {
            if(s[i]==s[i-1])
                A[i]=0;
            else
                A[i]=A[i-1]+1;
        }
        B[n-1]=0;
        for(int i=n-2;i>=0;i--)
        {
            if(s[i]==s[i+1])
                B[i]=0;
            else
                B[i]=B[i+1]+1;
        }
        if(s[0]=='L')
            cout<<1;
        else if(s[0]=='R')
            cout<<2+B[0];
        for(int i=0;i<n;i++)
        {
            int ans=1;
            if(s[i]=='L')
                ans+=A[i]+1;
            if(s[i+1]=='R')
                ans+=1+B[i+1];
            cout<<' '<<ans;
        }
        cout<<endl;
    }
}

C.

ai=d1^n * d2^n(d1,d2是ai的因数)
对于gcd有
gcd(a,b)=gcd(a+b,b)
且若gcd(a,b)=1,
则gcd(a,c)=gcd(a,c*b)=gcd(a,c * b^n)
现有gcd(d1,d2)=1,->gcd(d1+d2,d1)=1,gcd(d1+d2,d2)=1
->gcd(d1+d2,d1 * d2)=1,->gcd(d1+d2,d1^n * d2^n)

那么我们只要找到ai的两个互质因数即可

bool is_prime[20*N];//是否是质数,0为是,1为不是
int prime[20*N];//质数数组
int top=1;//质数的下标
int min_p[20*N];//最小质因数数组
int a[N],b[N];
void get_prime(int n){
    for(int i=2;i<=n;i++){
        if(!is_prime[i]){//是质数
            prime[top]=i;//存质数
            min_p[i]=i;//质数的最小质因数是本身
            top++;//下标后移
        }
        for(int j=1;j<top;j++){//最小到达遍历质数数组
            if(i*prime[j]>n)break;
            is_prime[i*prime[j]]=1;//标记质数的倍数即合数
            min_p[i*prime[j]]=prime[j];//质数的倍数的最小质因数是该质数
            if(i%prime[j]==0)break;//若i是之前质数的倍数,说明这个倍数会在后面的循环内被筛去,无需继续循环
        }
    }
}

void solve() {
    int n;cin>>n;
    get_prime(1e7+3);
    for(int i=1;i<=n;i++){
        int p;cin>>p;
        if(is_prime[p]==0)a[i]=-1,b[i]=-1;
        else{
            int k=min_p[p];
            while(p%k==0)p/=k;
            if(p==1)a[i]=-1,b[i]=-1;
            else a[i]=k,b[i]=p;
        }
    }
    for(int i=1;i<=n;i++)cout<<a[i]<<' ';
    cout<<endl;
    for(int i=1;i<=n;i++)cout<<b[i]<<' ';
}

第二个与d1互质因数只需用ai当ai%d1==0时不断除d1即可求出

posted @ 2023-11-24 12:39  WW爆米花  阅读(7)  评论(0编辑  收藏  举报