集美大学第九届程序设计竞赛

简介: 集美大学第九届程序设计竞赛

题解直通车:集美大学第9届校赛【出题人题解】 - 知乎 (zhihu.com)

补题补知识:

1.多边形叉积用来算多边形的面积的两倍

H-面积_集美大学第九届程序设计竞赛(同步赛) (nowcoder.com)

#include <bits/stdc++.h>
using namespace std;
int main() {
    long long x[6], y[6];
    for(int i=1; i<=5; ++i) cin>>x[i]>>y[i];
    x[0]=x[5]; y[0]=y[5];
    long long res=0;
    for(int i=1; i<=5; ++i)
        res += x[i]*y[i-1] - x[i-1]*y[i];
    cout<<abs(res);
    return 0;
}

2.F-区间_集美大学第九届程序设计竞赛(同步赛) (nowcoder.com)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
struct
{
    ll l,r;
}tr[N];
int n;
void solve()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%lld%lld",&tr[i].l,&tr[i].r);
    ll res=0;
    for(int B=59;B>=0;B--)
    {
        bool f=true;
        for(int i=1;i<=n;i++)
            if(~tr[i].r>>B&1)
            {
                f=false;
                break;
            }
       if(f)
       {
           res+=1ll<<B;
           for(int i=1;i<=n;i++)
              if(~tr[i].l>>B&1) tr[i].l=0;
       }
       else
       {
           for(int i=1;i<=n;i++)
              if((tr[i].r>>B&1)&&(~tr[i].l>>B&1)) tr[i].l=tr[i].r=(1ll<<B)-1;
       }
    }
    printf("%lld\n",res);
}
int main()
{
   int T=1;
   while(T--) solve();
    return 0;
}

3.I-逛孙厝的贝贝_集美大学第九届程序设计竞赛(同步赛) (nowcoder.com)

动态规划

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=310,M=90010,mod=1e9+7,K=1e7+10;
int n,m,k;
int w[N];
int Sum,sum[M];
int f[N][M];
int fac[K],inv[K];
int qmi(int a,int k,int p)
{
    int res=1;
    while(k)
    {
        if(k&1) res=(ll)res*a%p;
        a=(ll)a*a%p;
        k>>=1;
    }
    return res;
}
void init(int n)
{
    fac[0]=1;
    for(int i=1;i<=n;i++) fac[i]=(ll)fac[i-1]*i%mod;
    inv[n]=qmi(fac[n],mod-2,mod);
    for(int i=n;i;i--) inv[i-1]=(ll)inv[i]*i%mod;
}
int C(int a,int b)
{
    if(a<b) return 0;
    return (ll)fac[a]*inv[b]%mod*inv[a-b]%mod;
}
void solve()
{
    init(1e7);
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=m;i++) scanf("%d",&w[i]),Sum+=w[i];
    f[0][0]=1;
    for(int i=1;i<=m;i++)
    {
        sum[0]=0;
        for(int j=0;j<=Sum;j++)
            sum[j+1]=(sum[j]+f[i-1][j])%mod;
        for(int j=0;j<=Sum;j++)
            f[i][j]=(sum[j+1]-sum[max(0,j-w[i])]+mod)%mod;
    }
    if(n==m)
    {
        printf("%d\n",f[m][k]);
        return;
    }
    int ans=0;
    for(int i=0;i<=Sum;i++)
        ans=(ans+(ll)f[m][i]*C(k-i+n-m-1,n-m-1)%mod)%mod;
    printf("%d\n",ans);
}
int main()
{
   int T=1;
   while(T--) solve();
    return 0;
}

3.L-序列_集美大学第九届程序设计竞赛(同步赛) (nowcoder.com)

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&-x
typedef long long ll;
const int N=1e5+10;
int tr[N];
int n,a[N];
int l[N],r[N];
void add(int x)
{
    for(int i=x;i<=n;i+=lowbit(i)) tr[i]++;
}
int sum(int x)
{
    int res=0;
    for(int i=x;i;i-=lowbit(i)) res+=tr[i];
    return res;
}
void solve()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
        l[i]=i-1-sum(a[i]),add(a[i]);
    memset(tr,0,sizeof tr);
    for(int i=n;i;i--)
        r[i]=n-i-sum(a[i]),add(a[i]);
    int res=0;
    for(int i=1;i<=n;i++) res+=min(l[i],r[i]);
    printf("%d\n",res);
}
int main()
{
    int T=1;
    while(T--) solve();
    return 0;
}

4.M-循环节_集美大学第九届程序设计竞赛(同步赛) (nowcoder.com)

比赛时代码:

思路:看看当前l能不能更新到1的位置,r能不能更新到n的位置假如可以并且这个区间长度可以被整除说明这个区间是可以作为循环戒更新S串的

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,m,ne[N];
char p[N];
int l[N],r[N];
int main()
{
   scanf("%d%d%s",&n,&m,p+1);
   for(int i=2,j=0;i<=n;i++)
   {
       while(j&&p[i]!=p[j+1]) j=ne[j];
       if(p[i]==p[j+1]) j++;
       ne[i]=j;
   }
   int t=n;
   r[t]=n;
   while(ne[t]!=0) t=ne[t],r[t]=n;
   l[1]=1;
   for(int i=2;i<=n;i++)
   {
        int j=ne[i];
        l[i]=l[j];
   }
   int a,b;
   while(m--)
   {
       scanf("%d%d",&a,&b);
       a++,b++;
       if(l[a]==1&&r[b]==n&&n%(b-a+1)==0) puts("YES");
       else puts("NO");
   }
    return 0;
}

题解:

这是一个kmp经典应用,len=n−next[n]即是最短循环节的长度

一个字符串是否是原串的循环节,取决于这个串的左右端点取模len都需要等于0,并且r−l+1整除n

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int ne[N];
char s[N];
int n,m;
void solve()
{
   scanf("%d%d",&n,&m);
   scanf("%s",s+1);
   for(int i=2,j=0;i<=n;i++)
   {
       while(j&&s[i]!=s[j+1]) j=ne[j];
       if(s[i]==s[j+1]) j++;
       ne[i]=j;
   }
   int len=n-ne[n];
   if(!ne[n]) len=n;
   int l,r;
   while(m--)
   {
       scanf("%d%d",&l,&r);
       l++,r++;
       if(l==1&&r==n) puts("YES");
       else
       {
           if((l-1)%len==0&&r%len==0&&n%(r-l+1)==0) puts("YES");
           else puts("NO");
       }
   }
}
int main()
{
    int T=1;
    while(T--) solve();
    return 0;
}
相关文章
|
6月前
|
存储 算法 C++
西安石油大学2023年第三届里奇杯编程大赛(初赛)
西安石油大学2023年第三届里奇杯编程大赛(初赛)
23 0
|
11月前
桂林电子科技大学第三届ACM程序设计竞赛 E题
桂林电子科技大学第三届ACM程序设计竞赛 E题
58 0
|
11月前
桂林电子科技大学第三届ACM程序设计竞赛 F题
桂林电子科技大学第三届ACM程序设计竞赛 F题
58 0
|
11月前
桂林电子科技大学第三届ACM程序设计竞赛 H题
桂林电子科技大学第三届ACM程序设计竞赛 H题
45 0
|
11月前
桂林电子科技大学第三届ACM程序设计竞赛 D题
桂林电子科技大学第三届ACM程序设计竞赛 D题
73 0
|
11月前
桂林电子科技大学第三届ACM程序设计竞赛 B题
桂林电子科技大学第三届ACM程序设计竞赛 B题
51 0
|
11月前
桂林电子科技大学第三届ACM程序设计竞赛 C题
桂林电子科技大学第三届ACM程序设计竞赛 C题
86 0
|
11月前
桂林电子科技大学第三届ACM程序设计竞赛 J题
桂林电子科技大学第三届ACM程序设计竞赛 J题
70 0
|
11月前
桂林电子科技大学第三届ACM程序设计竞赛 I题
桂林电子科技大学第三届ACM程序设计竞赛 I题
54 0