中山Day5——普及

今天题目真是贼难呐。。。才38。。。

收获:树状数组单个修改

           树状数组区间修改


 

T1:旅行

题意:有n个数,问;从中取任意个数,他们的和为质数的方案数是多少?(n<=50)

暴力模拟即可,这里不讲。

见代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int n,ans,sum,a[551],b[551];
bool flag[551][10001];
bool pan(int x)
{
    if(x==1)
    return false;
    int i=2;
    while(i<=sqrt(x))
    {
        if(x%i==0)
        break;
        else
        i++;
    }
    if(i>sqrt(x))
    return true;
    else
    return false;
}
void dfs(int x)
{
    for(int i=b[x-1]+1;i<=n;i++)
    {
        if(flag[x][a[i]]==false)
        {
            sum+=a[i];
            flag[x][a[i]]=true;
            b[x]=i;
            if(pan(sum))
            {
                ans++;
            }
            dfs(x+1);
            b[x]=0;
            sum-=a[i];
        }
    }
}
bool cmp(int x,int y)
{
    return x<y;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    scanf("%d",&a[i]);
    sort(a+1,a+n+1,cmp);
    dfs(1);
    printf("%d",ans);
    return 0;
}

好题哉!!!


T2:神秘山庄

 见题:

翠亨村是一个神秘的山庄,并不是因为它孕育了伟人孙中山,更神秘的是山庄里有N只鬼、M只兔子,当然还有你。其中每秒钟:

 

1. 恰有两个生物遇到。

 

2. 任意两个生物之间相遇的概率是均等的。

 

如果两只兔子相遇,没有事情发生;如果两只鬼相遇,他们会互相厮打,最终一起死亡;如果鬼遇到兔子,兔子就会被吃掉;如果鬼遇到你,哈哈。。。。symbol就见不到你了;如果你遇到兔子,那么你可以选择杀或不杀(概率相等)。

 

问你能活着见symbol的概率。
 
显然:只有鬼死光了才能获胜。那么兔子就是什么用都没有的了,剩下的,若鬼是奇数,责必死无疑。若鬼是偶数,因为最后人鬼只能活一个,所以概率为1/(n+1)。
见代码:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
double n,m,a,sum=1;
int main()
{
    scanf("%lf%lf",&n,&m);
    a=m+1+n;
    if(int(n)%2==0)
    printf("%.6lf",1/(n+1));
    else
    printf("%.6lf",0);
    return 0;
}

好题哉!!!


T3:幸运锁

有一把幸运锁,打开它将会给你带来好运,但开锁时需要输入一个正整数(没有前导0)。幸运锁有一种运算,对于一个正整数,返回他的相邻两位数字间的差,如1135,运算结果为22(会去掉前导0)

现在已知只有经过反复运算最终结果为7的数才能打开这把锁,给你一个区间[a,b],问该区间中有多少个能打开幸运锁的幸运数。【限制】1<=a<=b<=10^9。
思路:暴力打表,暴力枚举。(据说有大佬用pascal打表AC)

见代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int a[101],b[101],flag,head;
bool pan(int x)
{
    flag=0;
    while(x!=0)
    {    
        flag++;
        b[flag]=x%10;
        x/=10;
    }
    for(int i=1;i<=flag;i++)
    a[i]=b[flag-i+1];
    while(flag>1)
    {
        head=1;
        while(a[1]==0)
        {
            for(int j=2;j<=flag;j++)
            {
                a[j-1]=a[j];
            } 
            flag-=1;
            if(flag==1)
            break;
        }
        for(int i=1;i<flag;i++)
        {
            a[head]=abs(a[i]-a[i+1]);
            head++;
            for(int j=i+2;j<=flag;j++)
            {
                a[j-1]=a[j];
            }    
            flag--;
        }
    }
    if(a[1]==7)
    return true;
    return false;
}
int main()
{
    freopen("lucky.in","r",stdin);
    freopen("lucky.out","w",stdout);
    int a1,b1,j,j1=0,ans=0;
    scanf("%d%d",&a1,&b1);
    for(int j=a1;j<=b1;j++)
    if(pan(j)==true)
    ans++; 
    printf("%d\n",ans);
    return 0;
}

好题哉!!!


T4:简单题

题意:给定一个序列,有两种操作:询问一段区间内的数字和、给一个区间内每个数加一个值。你需要回答每个询问。

思路:一看这题:呦呵!不是线段树区间修改的模板吗,秒做的说。

见代码:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
long long n,q,d,s,c1[100001],sum1[100001],c2[100001],a[100001];
char w;
long long lowbit(long long x)
{
    return x&(-x);
}
long long sum(long long c[],long long x)
{
    long long ret=0;
    while(x>0)
    {
        ret+=c[x];
        x-=lowbit(x);
    }
    return ret;
}
void add(long long c[],long long x,long long y)
{
    while(x<=n)
    {
        c[x]+=y;
        x+=lowbit(x);
    }
}
int main()
{
    freopen("simple.in","r",stdin);
    freopen("simple.out","w",stdout);
    scanf("%ld%ld",&n,&q);
    for(int i=1;i<=n;i++)
    {
        scanf("%ld",&a[i]);
        sum1[i]=sum1[i-1]+a[i];
    }
    for(int j=1;j<=q;j++)
    {
        cin>>w;
        scanf("%ld%ld",&s,&d);
        if(int(w)==int('Q'))
        {
            long long suml=sum1[s-1]+s*sum(c1,s-1)-sum(c2,s-1);
            long long sumd=sum1[d]+(d+1)*sum(c1,d)-sum(c2,d);
            printf("%ld\n",sumd-suml); 
        }
        else 
        {
            long long cost;
            scanf("%ld",&cost);
            add(c1,s,cost);
            add(c1,d+1,-cost);
            add(c2,s,s*cost);
            add(c2,d+1,-(d+1)*cost);
        }
    }
    return 0;
}

好题哉!!!

 

posted @ 2019-08-05 20:00  青殇  阅读(136)  评论(1编辑  收藏  举报