蘭州大學第一屆『飛馬杯』程序設計競賽(同步賽)

傳送門

★★比賽新機制★★

題解:遞推

​sum=a1+a2+...an

如果順序爲a1,a2,a2...an,那麼罰時爲S1=n*a1+(n-1)*a2+(n-2)*a3....+an

如果順序爲a2,a3....,an,a1,那麼罰時爲S2=n*a2+(n-1)*a3+....a1

即Si+1=S1-n*ai+sum.

O(N)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define LL long long

int T;

LL s[500003];

LL tmp,ans,sum;

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        tmp=0;sum=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&s[i]);
            sum+=s[i];
            tmp+=(n-i+1)*s[i];
        }
        ans=tmp;
        for(int i=1;i<=n;i++)
        {
            ans=min(ans,tmp-n*s[i]+sum);
            tmp=tmp-n*s[i]+sum;
        }
        tmp=0;
        for(int i=n;i>=1;i--)
        {
            tmp+=i*s[i];
        }
        ans=min(ans,tmp);
        for(int i=n;i>=1;i--)
        {
            ans=min(ans,tmp-n*s[i]+sum);
            tmp=tmp-n*s[i]+sum;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

★★生命的遊戲★★

模擬

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;


int T;

int n,k;

int a[101][101],b[101][101],c[101][101];

int js1,js;

int dx[]={0,0,1,1,1,-1,-1,-1};
int dy[]={1,-1,0,-1,1,0,1,-1};

bool check()
{
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(a[i][j]!=b[i][j]) return false;
        }
    }
    return true;
}

int count_alivecell(int x,int y)
{
    int res=0;
    for(int i=0;i<8;i++)
    {
        int nowx=(x+dx[i]+n)%n;
        int nowy=(y+dy[i]+n)%n;
        if(a[nowx][nowy]) res++;
    }
    return res;
}

void slove()
{
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            c[i][j]=a[i][j];
        }
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            int cnt=count_alivecell(i,j);
            if(a[i][j])
            {
                if(cnt>3||cnt<2) c[i][j]=0,js1--;
            }else
            {
                if(cnt==3) c[i][j]=1,js1++;
            }
        }
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            a[i][j]=c[i][j];
        }
    }
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&k);
        js1=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                scanf("%d",&a[i][j]);
                b[i][j]=a[i][j];
                if(a[i][j]) js1++;
            }
        }
        js=js1;
        bool flag=false;
        for(int i=1;i<=k;i++)
        {
            slove();
          //  for(int j=0;j<n;j++)
        //    {
         ///       for(int kk=0;kk<n;kk++)
          //      {
          //          cout<<a[j][kk]<<"--";
          //      }
          //      cout<<endl;
         //   }
            if(js1==js&&check())
            {
                flag=true;
                printf("YES\n%d\n",i);
                break;
            }
        }
        if(!flag) printf("NO\n");
    }
    return 0;
}

★★飛馬分隔符★★

#include<iostream>
#include<cstdio>
using namespace std;

char s[100002];

char stac[100002];

int top;

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,ans=0;
        top=0;
        scanf("%d",&n);
        scanf("%s",s+1);
        for(int i=1;i<=n;i++)
        {
            if(s[i]=='F'&&!top) stac[++top]='F';
            if(s[i]=='e'&&stac[top]=='F') stac[++top]='e';
            if(s[i]=='i'&&stac[top]=='e') stac[++top]='i';
            if(s[i]=='M'&&stac[top]=='i') stac[++top]='M';
            if(s[i]=='a'&&stac[top]=='M') ans++,top=0;
        }
        cout<<ans<<endl;
    }
    return 0;
}

★★溫暖的力量★★

題目大意:x能否被質數的和表示,若能,能被幾個質數表示。

題解:

當 n爲大於3的奇數時,可以分爲若干個2和一個3當n爲大於3的偶數時,可以分爲若干個2。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int T;
int s[1000002];

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        int x;
        scanf("%d",&x);
       if(x<=3) printf("-1\n");
        else printf("%d\n",x/2);
    } 
    return 0;
}

★★平形四邊行★★

四個點能形成“平形四邊行”的充要條件是,存在一種方案,將四個點均分爲兩組,每組的兩個點形成一條線段,這兩條線段的中點重合。

#include<iostream>
#include<map>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100001

int xx[N],yy[N];

struct Node
{
    int x,y;
    Node(){}//....
    Node(int x,int y):
    x(x),y(y){}
    bool operator!=(const Node& t) {
        return x!=t.x&&x!=t.y&&y!=t.x&&y!=t.y;
    }
};

map<pair<int,int>,Node>mp;

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&xx[i],&yy[i]);
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            int tx=xx[i]+xx[j];
            int ty=yy[i]+yy[j];
            if(!mp.count({tx,ty}))
            {
                mp[{tx,ty}]=Node(i,j);
            }else if(mp[{tx,ty}]!=Node(i,j)) 
            {
                puts("YES");
                printf("%d %d %d %d\n",i,j,mp[{tx,ty}].x,mp[{tx,ty}].y);
                return 0;
            }
        }
    }
    printf("NO");
    return 0;
}

★★翻滾吧硬幣★★

只要知道硬幣翻滾的距離是圓心移動的距離就好辦

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;

int T;

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        LL a[4];
        for(int i=1;i<=3;i++) scanf("%lld",&a[i]);
        sort(a+1,a+3+1);
        LL l1,l2,l3;
        l1=a[1]+a[2];
        l2=a[1]+a[3];
        l3=a[2]+a[3];
        double z=1.*(l1*l1+l2*l2-l3*l3)/(2*l1*l2);
        double p=1.*(l1*l1+l3*l3-l2*l2)/(2*l1*l3);
        z=z*-1.;p=p*-1.;
        z=acos(z);
        p=acos(p);
        double ans=l2*z+l3*p;
        ans=ans*2/(3.14159265358979323*2*a[3]);
        printf("%.15lf\n",ans);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章