2019年华南理工大学程序设计竞赛

 

目录

 

C 六学家的困惑(模拟+思维)

E 数独挑战(dfs)

H Parco_Love_GCD(思维)

I 炒股(思维)

L 石头剪刀布(水题)


C 六学家的困惑(模拟+思维)

【题意】

有两个字符串,每次可以从两个字符串的两端取一个数字,需要最终组成的字符串数字最大。

【解题思路】

扫描二维码关注公众号,回复: 5969694 查看本文章

如果给的是一个字符串会不会简单一点呢...?答案是肯定的,直接从两端找就可以啦,如果两端的数一样,那么继续往里找,从里面的数比较大的一端先取,然后就得到了一个字符串能够组成的最大字符串,同理另一个字符串也先做这样的处理。最后把他们组合起来再做一次处理。但是这里需要注意,第二个字符串要倒序和第一个字符串组合,这个应该很容易理解。

【代码】

#include<bits/stdc++.h>
using namespace std;
string s1,s2;
string f1(string s)
{
    string p;
    int l=0,r=s.size()-1;
    while(l<=r)
    {
        if(s[l]>s[r])p=p+s[l++];
        else if(s[l]<s[r])p=p+s[r--];
        else
        {
            int tl=l+1,tr=r-1,f=0;
            while(tl<=tr)
            {
                if(s[tl]>s[tr])
                {
                    f=1;
                    p=p+s[l++];
                    break;
                }
                else if(s[tl]<s[tr])
                {
                    f=1;
                    p=p+s[r--];
                    break;
                }
                else
                {
                    tl++;
                    tr--;
                }
            }
            if(!f)p=p+s[l++];
        }
        //cout<<p<<endl;
    }
    return p;
}
int main()
{
    int T,kase=1;
    scanf("%d",&T);
    while(T--)
    {
        cin>>s1>>s2;
        string ts1,ts2,ss;
        ts1=f1(s1);
        ts2=f1(s2);
        ss=ts1;
        for(int i=ts2.size()-1;i>=0;i--)
            ss=ss+ts2[i];
        string ans=f1(ss);
        printf("Case #%d: ",kase++);
        cout<<ans<<endl;
    }
}

E 数独挑战(dfs)

【题意】9*9的数独游戏。往空格内填1-9的数字,要求每9个格子,每一列每一行不能出现重复数字。

【解题思路】很经典的一道dfs题...然而我敲了很久 coding能力真的不行

用row[i][x]标记第i出现了第x个数,同理col标记列,t标记方格。然后dfs暴搜即可,如果y=8时,记得要搜下一行~

【代码】

#include<bits/stdc++.h>
using namespace std;
int flag=0;
int a[15][15],vis[15],col[15][15],row[15][15],t[15][15][15];
void dfs(int x,int y)
{
    if(flag)return;
    if(x==9)
    {
        flag=1;
        for(int i=0;i<9;i++)
        {
            printf("%d",a[i][0]);
            for(int j=1;j<9;j++)
                printf(" %d",a[i][j]);
            printf("\n");
        }
        return;
    }
    if(!a[x][y])
    {
        for(int i=1;i<=9;i++)
        {
            if(!row[x][i] && !col[y][i] && !t[x/3][y/3][i])
            {
                a[x][y]=i;
                row[x][i]=col[y][i]=t[x/3][y/3][i]=1;
                if(y==8)dfs(x+1,0);
                else dfs(x,y+1);
                a[x][y]=0;
                row[x][i]=col[y][i]=t[x/3][y/3][i]=0;
            }
        }
    }
    else
    {
        if(y==8)dfs(x+1,0);
        else dfs(x,y+1);
    }
}
int main()
{
    for(int i=0;i<9;i++)
    {
        for(int j=0;j<9;j++)
        {
            scanf("%d",&a[i][j]);
            if(a[i][j])
            {
                int x=a[i][j];
                row[i][x]=col[j][x]=t[i/3][j/3][x]=1;
            }
        }
    }
    dfs(0,0);
}
/*
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 0 0 0
0 9 8 0 0 0 0 6 0
8 0 0 0 6 0 0 0 3
4 0 0 8 0 3 0 0 1
7 0 0 0 2 0 0 0 6
0 6 0 0 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
*/

H Parco_Love_GCD(思维)

【题意】

【解题思路】

时限3s…其实很暴力,稍微优化一下即可。根据gcd的性质,数越多gcd肯定越小,所以当一个一个遍历下去的时候,如果gcd已经和整个数组的gcd一样的话,就没必要再往下做了,直接计算后退出即可。但是如果没有这个优化是过不了的。

【代码】

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=5e5+5;
const LL mod=1e9+7;
LL a[maxn];
vector<LL>v[maxn];
LL gcd(LL a,LL b)
{
    while(b)
    {
        LL x=a%b;
        a=b;
        b=x;
    }
    return a;
}
int main()
{
    int n;
    LL c=0,ans=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%lld",&a[i]);
    for(int i=1;i<=n;i++)
        c=gcd(c,a[i]);
    for(int i=1;i<=n;i++)
    {
        LL x=0;
        for(int j=i;j<=n;j++)
        {
            x=gcd(x,a[j]);
            if(x==c)
            {
                ans=(ans+x*(n-j+1))%mod;
                break;
            }
            else ans=(ans+x)%mod;
        }
    }

    printf("%lld\n",ans);
}

I 炒股(思维)

【题意】

胡老师每天能够卖出或买入股票,并且每天只能持有1支股票,给出n天股票的价钱,问在n天之后他最多能靠炒股赚多少钱。

【解题思路】

写写样例然后模拟模拟就可以发现,问题可以转化为数组中有的上升的子序列两端点的差值之和。比如8 7 3 6 9 2 5就等于9-3+5-2=9.

【代码】

#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+5;
typedef long long LL;
LL a[maxn];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%lld",&a[i]);
    LL ans=0,now=a[0];
    for(int i=1;i<n;i++)
    {
        if(a[i-1]>=a[i])
        {
            ans+=a[i-1]-now;
            now=a[i];
        }
    }
    if(a[n-1]>a[n-2])ans+=a[n-1]-now;
    printf("%lld\n",ans);
}

L 石头剪刀布(水题)

【代码】

水题就不解释了...

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        string str;
        cin>>str;
        if(str=="Scissors")puts("Rock");
        else if(str=="Rock")puts("Paper");
        else puts("Scissors");
    }
}

猜你喜欢

转载自blog.csdn.net/qq_39826163/article/details/89293777
今日推荐