新疆大学ACM-ICPC程序设计竞赛五月月赛(同步赛)(B,C,F)

链接: https://www.nowcoder.com/acm/contest/116/B
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

杨老师给同学们玩个游戏,要求使用乘法和减法来表示一个数,他给大家9张卡片,然后报出一个数字,要求大家用表达式的形式来表示出这个数
100 可以表示为这样的形式:100 = 129*67-8543 , 还可以表示为:100 = 13*489-6257
注意特征:表达式中,数字1~9分别出现且只出现一次(不包含0)。
类似这样的表达式,100 有 20 种表示法。
题目要求:
从标准输入读入一个正整数N(N<1000 * 1000)
程序输出该数字用数码1~9不重复不遗漏地组成的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!

输入描述:

一个正整数N

输出描述:

输出有多少种表示法
示例1

输入

100

输出

20

备注:

注意只有一个乘法和一个减法,*号保证在-的前面

不用想太多,直接dfs就可以了,我一直分析复杂度没敢写,直接暴力不要想!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int vis[100];
int a[1000];
int Count,n;
int sum(int i,int j)
{
    int k;
    int s=0;
    for(k=i;k<=j;k++)
    {
        s=s*10+a[k];
    }
    return s;
}
void judge()
{
    int i,j,k;
    int x,y,z;
    for(i=1;i<=7;i++)
    {
        for(j=i+1;j<=8;j++)
        {
            x=sum(1,i);
            y=sum(i+1,j);
            z=sum(j+1,9);
            if(x*y-z==n) Count++;
        }
    }
}
int dfs(int x)
{
    int i;
    if(x==10)
    {
        judge();
        return 1;
    }
    for(i=1;i<=9;i++)
    {
        if(!vis[i])
        {
            a[x]=i;
            vis[i]=1;
            dfs(x+1);
            vis[i]=0;
        }
    }
    return 1;
}
int main()
{
    scanf("%d",&n);
    dfs(1);
    printf("%d\n",Count);
}
链接: https://www.nowcoder.com/acm/contest/116/C
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

杨老师认为他的学习能力曲线是一个拱形。勤奋的他根据时间的先后顺序罗列了一个学习清单,共有n个知识点。但是清单中的知识并不是一定要学习的,可以在不改变先后顺序的情况下有选择的进行学习,而每一个知识点都对应一个难度值。杨老师希望,后学习的知识点的难度一定不低于前一个知识点的难度(i<j时ai<=aj),而可能存在一个临界点,在临界点以后,他希望后学习的知识点的难度一定不高于前一个知识点的难度(i<j时ai>=aj)。杨老师想尽可能多的学习知识。请问:杨老师最多可以学习多少知识?

输入描述:

第一行:一个整数n(0<n<500000)接下来一行:n个整数,第i个整数ai(0<=ai<500000)表示第i道题目的难度。

输出描述:

一行一个整数,表示杨老师最多可以学习多少个知识。
示例1

输入

5
1 4 2 5 1

输出

4

双向LIS,要求求一个单调递增+一个单调递减的最长序列,nlogn的模板往上刚,单调递增的就正常的做,单调递减的就是方向做一次最长上升子序列,也就是从后往前是单调递增,那么从前往后就是单调递减,把每一个值中的对应的长度找出来然后相加-1就是在该位置的值,注意二分中的stack[mid]>a[i] 时,r=mid-1,所以最后求出来的r+1一定就是比a[i]第一个大的值。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int a[500009];
int stack[500009];
int L[500009];
int R[500009];
int main()
{
    int n,i,j,k,top;
    scanf("%d",&n);
    for(i=0;i<=n-1;i++) scanf("%d",&a[i]);
    stack[0]=-9999;
    top=0;
    for(i=0;i<=n-1;i++)
    {
        if(a[i]>=stack[top])
        {
            top++;
            stack[top]=a[i];
        }
        else
        {
            int l=1,r=top,mid;
            while(l<=r)
            {
                mid=(l+r)/2;
                if(stack[mid]>a[i])
                {
                    r=mid-1;
                }
                else
                {
                    l=mid+1;
                }
            }
            stack[r+1]=a[i];
        }
        L[i]=max(top,L[i]);
    }
    stack[0]=-9999;
    top=0;
    for(i=n-1;i>=0;i--)
    {
        if(a[i]>=stack[top])
        {
            top++;
            stack[top]=a[i];
        }
        else
        {
            int l=1,r=top,mid;
            while(l<=r)
            {
                mid=(l+r)/2;
                if(stack[mid]>a[i])
                {
                    r=mid-1;
                }
                else
                {
                    l=mid+1;
                }
            }
            stack[r+1]=a[i];
        }
        R[i]=max(top,R[i]);
    }
    int ans=0;
    for(i=0;i<=n-1;i++)
    {
        ans=max(ans,L[i]+R[i]-1);
        //printf("L==%d  R==%d\n",L[i],R[i]);
    }
    printf("%d\n",ans);
}
链接: https://www.nowcoder.com/acm/contest/116/F
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

我们知道有一种神奇的排序方法叫做猴子排序,就是把待排序的数字写在卡片上,然后让猴子把卡片扔在空中,等落下的时候观察这些卡片是否从左到右已经排序完成(我们认为不会发生卡片落地后叠在一起的情况)如果有序则排序完成,否则让猴子再扔一遍,直到卡片有序,那么问题来了,给你N个卡片,每个卡片上写着一个大写字母,请问猴子第一次扔这些卡片就按字典序排序完成的概率有多大?

输入描述:

第一行是一个整数N(1<N<100)表示给猴子N张卡片,接下来是一个长度为N的字符串,代表这些卡片上所写的字母。

输出描述:

输出一行,表示猴子排序第一次就成功的概率(用分子为1的分数表示)。
示例1

输入

7
SCIENCE

输出

1/1260

大数模板,分子是各阶乘的乘积,分母是n!,直接大数就可以了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int d[1000];
char s[100];
string mul(string a,int b)
{
    string c;
    char s;
    int len=a.length();
    int ok=0;
    for(int i=len-1; i>=0; i--)
    {
        int temp=(a[i]-'0')*b+ok;
        ok=temp/10;
        s=temp%10+'0';
        c=s+c;
    }
    while(ok)
    {
        s=ok%10+'0';
        c=s+c;
        ok/=10;
    }
    return c;
}
string div(string a,int b)
{
    string c;
    int len=a.length();
    int ans=0;
    char s;
    for(int i=0;i<len;i++)
    {
        ans=ans*10+a[i]-'0';
        s=ans/b+'0';
        ans%=b;
        c+=s;
    }
    int pos=0;
    while(pos<len && c[pos]=='0') pos++;
    if(pos==len) return "0";
    return c.substr(pos);
}
int main()
{
    int i,k,n,j;
    scanf("%d%s",&n,s);
    for(i=0; i<=strlen(s)-1; i++)
    {
        k=s[i]-'A';
        d[k]++;
    }
    string a="1";
    for(i=1; i<=n; i++)
    {
        a=mul(a,i);
    }
    //cout<<a<<endl;
    for(i=0;i<=25;i++)
    {
        if(d[i]>=2)
        {
            for(j=d[i];j>=2;j--)
            {
                a=div(a,j);
            }
        }
    }
     cout<<"1/"<<a;

}


猜你喜欢

转载自blog.csdn.net/keepcoral/article/details/80157189
今日推荐