2020牛客多校第三场

A.Clam and Fish

贪心,有鱼一定钓鱼,没有看后面的无鱼地有多少,可以用前缀和处理出来,比较一下就行了

代码:

#include
using namespace std;
#define ll long long
#define pi acos(-1)
const int maxn=2e6+10;
const int mod=1e9+7;
int n;
char a[maxn];
int s[maxn];
int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        scanf("%s",a+1);
        int x=0;//鱼饵数
        int ans=0;
        for(int i=1;i<=n;i++)s[i]=0;
        for(int i=1;i<=n;i++)
            if(a[i]=='0'||a[i]=='1')s[i]=s[i-1]+1;
            else s[i]=s[i-1];
        for(int i=1;i<=n;i++)
        {
            if(a[i]=='0'){
                if(x){
                    ans++;
                    x--;
                }
            }
            if(a[i]=='2'||a[i]=='3')ans++;
            if(a[i]=='1'){
                int y=s[n]-s[i];
                if(y>x)x++;
                else {
                    if(x){
                        ans++;
                        x--;
                    }
                }
            }
        }
        printf("%d\n",ans);
    }   
    return 0;
}

B.Classical String Problem

不难发现这个字符串的操作不管如何首尾相连后都是一样的,因此我们可以只看首位的位置就可以处理出当时状态的字符串了

代码:

#include
using namespace std;
#define ll long long
#define sc(a) scanf("%d",&a);
#define pf printf
#define pi acos(-1)
const int mod=1e9+7;
const int N=2e6+10;
int n,l;
char x[N],op;
int main()
{
    cin>>x;
    l=strlen(x);
    scanf("%d\n",&n);
    int fs=0,a;
    while(n--)
    {
        scanf("%c %d\n",&op,&a);
        if(op=='A')
        {
            printf("%c\n",x[(fs+a-1)%l]);
        }
        else
        {
            fs+=a+l;
            fs%=l;
        }
    }
     
    return 0;
}

C.Operation Love

左右手,计算几何题,队友A的,tql,%%%%%

代码:

#include
using namespace std;
#define ll long long
#define pi acos(-1)
const int maxn=2e6+10;
const int mod=1e9+7;
double eps=1e-4;
struct cc{
    double x,y;
}p[25];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        double mmax=0,m[30],k1,k2,b1,b2,c1,c2,c3;
        int a=-1,f=1;
        for(int i=0;i<20;i++)
            scanf("%lf %lf",&p[i].x,&p[i].y);
        for(int i=0;i<20;i++)
        {
            m[i]=(p[i].x-p[(i+1)%20].x)*(p[i].x-p[(i+1)%20].x)+(p[i].y-p[(i+1)%20].y)*(p[i].y-p[(i+1)%20].y);
            if(m[i]>mmax)
                mmax=m[i],a=i;
        }
        if(p[a].x-p[(a+1)%20].x==0)
            c1=pi/2;
        else
        {
            k1=(p[a].y-p[(a+1)%20].y)/(p[a].x-p[(a+1)%20].x);
            c1=atan(k1);
        }
        if(p[(a+19)%20].x-p[(a+2)%20].x==0)
            c2=pi/2;
        else
        {
            k2=(p[(a+19)%20].y-p[(a+2)%20].y)/(p[(a+19)%20].x-p[(a+2)%20].x);
            c2=atan(k2);
        }  
        c3=atan(2.0/9);
        //cout<

D.Points Construction Problem

构造题,只要思路理顺应该不会出错,NO的状态是在最小和最大之外,最大很好理解就是没有相邻,最小就是最接近正方形的图形,构造就行了

代码:

#include
using namespace std;
#define ll long long
#define pi acos(-1)
const int maxn=2e6+10;
const int mod=1e9+7;
double eps=1e-4;
int x[100],y[100],t;
int main()
{
    int t,f[55],k=0,s=0,p=0;
    f[1]=4,f[2]=6;
    for(int i=3;i<=50;i++)
    {
        if(k)
        {
            k--;
            f[i]=f[i-1];
        }
        else
        {
            if(p==0)
            s++;
            p=1-p;
            k=s;
            f[i]=f[i-1]+2;
        }
    }
    cin>>t;
    int n,m,ans;
    while(t--)
    {
        cin>>n>>m;
        if(m>4*n||m=0)
            {
                ans=0;
                k=sqrt(i);
                for(int j=1;j<=k;j++)
                {
                    for(int l=1;l<=k;l++)
                    {
                        ans++;
                        x[ans]=j;
                        y[ans]=l;
                    }
                }
                p=i-k*k;
                for(int j=1;j<=min(p,k);j++)
                {
                    ans++;
                    x[ans]=j;
                    y[ans]=k+1;
                }
                p-=min(p,k);
                for(int j=1;j<=p;j++)
                {
                    ans++;
                    x[ans]=k+1;
                    y[ans]=j;
                }
                ll o=m-f[i]-2*(n-i);
                 
                for(int q=1;q<=o/2;q++)
                {
                    ans++;
                    x[ans]=i+10+q;
                    y[ans]=i+10+q;
                }
                ll u=n-i-o/2;
                 
                for(int q=1;q<=u;q++)
                {
                    ans++;
                    x[ans]=1-q;
                    y[ans]=1;
                }
                break;
            }
        }//cout<

E.Two Matchings

dp,不难发现如果是一个序列一定是相邻的两个互指最优,那第二个序列不能和第一个序列有一样的指针,这时不一定是越少越优(WA出的道理QAQ),那我们可以用dp来解决这个问题,首先dp[i]可以由dp[i-4]+四个一组方案和dp[i-6]+六个一组方案推导得到,那我们只要求出最小即可,当然还要先设定初始值dp[4],dp[6],dp[8]

代码:

#include
using namespace std;
#define ll long long
#define sc(a) scanf("%d",&a);
#define pf printf
#define pi acos(-1)
const int mod=1e9+7;
const int N=2e6+10;
int n,l,t;
int a[N],dp[N];
char x[N],op;
int main()
{
    cin>>t;
    while(t--)
    {
        cin>>n;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        sort(a+1,a+1+n);
        ll ans=0;
        for(int i=1;i<=n;i+=2)
        {
            ans+=(a[i+1]-a[i]);
        }
        dp[4]=a[3]+a[4]-a[1]-a[2];
        dp[6]=a[6]-a[1]+a[5]-a[4]+a[3]-a[2];
        dp[8]=dp[4]+a[8]+a[7]-a[6]-a[5];
        for(int i=10;i<=n;i+=2)
        {
            dp[i]=min(dp[i-4]+a[i]+a[i-1]-a[i-2]-a[i-3],dp[i-6]+a[i]+a[i-1]+a[i-3]-a[i-4]-a[i-5]-a[i-2]);  
        }
        ans+=dp[n];
        cout<

L.Problem L is the Only Lovely Problem

签到

剩下的还没补,补了再加

你可能感兴趣的:(牛客,ACM)