zoukankan      html  css  js  c++  java
  • 牛客小白赛23

    A.不会状压,用dfs,n比较小,枚举是否消灭某一行,消灭行数上限判断 还需要消灭多少列,多处用剪枝。

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<math.h>
    #include<string>
    #include<map>
    #include<queue>
    #include<stack>
    #include<set>
    #include<ctime>
    #define ll long long
    #define inf 0x3f3f3f3f
    const double pi=3.1415926;
    const double eps=1e-9;
    using namespace std;
     
     
    int n,m,a,b;
    char s[25][100005];
    int l[100005];///列上敌人的总数
    int vis[25];///0表示没有该行没有消灭 1表示该行消灭了
    bool flag;
     
    bool check()
    {
        memset(l,0,sizeof(l));
        int res=0;///还需要消灭的列数
        for(int i=0;i<n;i++)
        {
            if(vis[i]==0)///只需要计算没有被消灭的行
            {
                for(int j=0;j<m;j++)
                    if(s[i][j]=='*' && l[j]==0 )
                    {
                        res++;
                        l[j]=1;
                    }
            }
        }
        if(res<=b)
            return true;
        else
            return false;
    }
     
     
    void dfs(int x,int num)///当前行  已经消灭的的行的数量
    {
        if(x==n)
        {
            if(a==num && check())///尽量消灭多的行,技能不用白不用,免得check太多超时
                flag=true;
            return;
        }
        if(flag)///一有机会就剪枝
            return;
        vis[x]=0;
        dfs(x+1,num);///此行不消灭
        if(flag)///一有机会就剪枝
            return;
        if(num<a)///还有消灭行的次数,此行消灭
        {
            vis[x]=1;
            dfs(x+1,num+1);
        }
    }
     
     
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            memset(vis,0,sizeof(vis));
            flag=false;
            scanf("%d%d%d%d", &n, &m, &a, &b);
            getchar();
            for(int i=0;i<n;i++)
                scanf("%s",s[i]);
            getchar();
            dfs(0,0);
            if(flag)
                printf("yes
    ");
            else
                printf("no
    ");
     
        }
     
        return 0;
    }
    A

    B:先用欧拉筛打出素数表,唯一分解定理对p分解质因数,对每一个质因数x,阶乘至少要多少能解决掉这些质因数。

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<math.h>
    #include<string>
    #include<map>
    #include<queue>
    #include<stack>
    #include<set>
    #include<ctime>
    #define ll long long
    #define inf 0x3f3f3f3f
    const double pi=3.1415926;
    const double eps=1e-9;
    using namespace std;
     
    const int maxx=1000005;
    int prime[maxx];
    int vis[maxx];
    int num[32005];
    int cnt;
    int p;
     
    void init()
    {
        memset(vis,true,sizeof(vis));
        vis[0]=vis[1]=false;
        cnt=0;
        for(int i=2;i<=maxx;i++)
        {
            if(vis[i])
                prime[cnt++]=i;
            for(int j=0;j<cnt && prime[j]*i<=maxx;j++)
            {
                vis[ i*prime[j] ]=false;
                if(i%prime[j]==0) break;
            }
        }
    }
     
    int find(int k,int x)///找k个x,阶乘至少要多少,x是素数
    {
        int i=0;
        int now=0;//目前提供了多少k
        for(i=x;k>0;i=i+x){
            //printf("i=%d k=%d x=%d
    ",i,k,x);
            int temp=i;
            while(temp%x==0){
                k--;
                temp=temp/x;
     
            }
     
        }
        return i-x;
    }
     
    int main()///对p分解质因子
    {
     
        init();/*
        int ans=find(7,2);
        printf("ans=%d
    ",ans);*/
        int t;
        scanf("%d",&t);
        while(t--){
            scanf("%d",&p);///p<1e9
            memset(num,0,sizeof(num));///质因子的数量
            int maxx=0;
            for(int i=0;prime[i]<32000 && prime[i]<=p;i++){
                int temp=0;
                while(p%prime[i]==0){
                    p=p/prime[i];
                    temp++;
     
                }
                maxx=max(maxx,find(temp,prime[i]));
                //printf("sushu=%d temp=%d maxx=%d
    ",prime[i],temp,maxx);
            }
            if(p>0)///大素数
                maxx=max(maxx,p);
            printf("%d
    ",maxx);
        }
        return 0;
    }
    B

    C:完全图是指每两个点都有边直接相连的图,分离出第一个联通分量需要删除n-1条边,第二个需要删除n-2,以此类推直到最后两个点删除1条边。等差求和二分查找项数,变量太大开启Java大数杀招。

    import java.math.BigInteger;
    import java.util.*;
     
    public class Main {
        public static void main(String[] args) {
            Scanner scan=new Scanner(System.in);
            BigInteger two=BigInteger.valueOf(2);
            int t=scan.nextInt();
            while(t>0) {
                t--;
                long n=scan.nextLong();
                long m=scan.nextLong();
                long l=1,r=n-1,mid=0,ans=0;;
                //完全图,任意两点都有边,分离出一个第一个连通分量要删n-1,第二个n-2
                //n-1  n-2 n-3 ... 1 等差求和  有x项
                //(n-1 + n-x) * x / 2
                while(l<=r) {
                    mid=(l+r)/2;//项数
                    BigInteger sum=BigInteger.valueOf(2*n-1-mid).multiply(BigInteger.valueOf(mid)).divide(two);
                    //sum=(2*n-1-mid)*mid/2
                    //System.out.println("l="+l+" r="+r+" mid="+mid+" sum="+sum);
                    if(sum.compareTo(BigInteger.valueOf(m))<=0) {
                        ans=mid;
                        l=mid+1;
                    }else
                        r=mid-1;
                } 
                System.out.println(ans+1);
            }
        }
         
    }
    C

    E:类似这种题,把代码放到编译器运行一下会发现答案都一样。

    G:记录每条边需要用多少次,用得多的赋值小一点的权值。dfs中,记录以x为根的子树的规模大小,一条边用的次数=两点的子树规模相乘。

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<math.h>
    #include<string>
    #include<map>
    #include<queue>
    #include<stack>
    #include<set>
    #include<ctime>
    #define ll long long
    #define inf 0x3f3f3f3f
    const double pi=3.1415926;
    const double eps=1e-9;
    using namespace std;
     
    vector<int>a[100005];
    int vis[100005];
    int num[100005];
    ll edge[100005];
    int t,n,k,idx;
     
    struct node{
        int x;
        int val;
    };
     
    void dfs(int x,int last)///当前点,父节点
    {
        num[x]=1;
        int len=a[x].size();
        for(int i=0;i<len;i++){
            int v=a[x][i];
            if(v!=last){
                dfs(v,x);
                num[x]+=num[v];///以u为根节点的子树的规模
                ///edge[idx++]=1ll*num[x]*num[v];//不可以这样写,因为num[x]还在累加之中
                edge[idx++]=1ll*num[v]*(n-num[v]);///x和v这条边用过的次数=两边子树的大小相乘
     
            }
     
        }
    }
     
    int main()
    {
        scanf("%d",&n);
        idx=0;
        for(int i=1;i<n;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            a[x].push_back(y);
            a[y].push_back(x);
        }
        dfs(1,-1);
        sort(edge,edge+idx);
        ll ans=0;
        for(int i=0;i<idx;i++)
            ans=ans+(--n)*edge[i];
        printf("%lld
    ",ans);
     
        return 0;
    }
    G

    H:全部看出二进制,手动模拟一下进位,从大到小填背包,能填满的话第一次肯定会增加到230

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<math.h>
    #include<string>
    #include<map>
    #include<queue>
    #include<stack>
    #include<set>
    #include<ctime>
    #define ll long long
    #define inf 0x3f3f3f3f
    const double pi=3.1415926;
    const double eps=1e-9;
    using namespace std;
     
    int two[31];
    struct node{
        int x;
        int id;
        int vis;
    };
     
    node k[100005];
    int m;
    void init(){
        two[0]=1;
        for(int i=1;i<31;i++)
            two[i]=2*two[i-1];
    }
     
     
     
    bool cmp(node p1,node p2){
        return p1.id<p2.id;
    }
     
    bool cmp2(node p1,node p2){
        return p1.x<p2.x;
    }
     
    int main()
    {
        init();
        int t;
        scanf("%d",&t);
        bool flag;
        while(t--){
            flag=false;
            scanf("%d",&m);
            for(int i=0;i<m;i++)
                scanf("%d",&k[i].x),k[i].id=i,k[i].vis=0;
            sort(k,k+m,cmp2);
            ll sum=two[30];
            ll now=0;
     
            for(int i=m-1;i>=0 && now<sum;i--){
                now+=two[ k[i].x ];
                k[i].vis=1;
                if(now==sum)
                    flag=true;
            }
            if(flag){
                sort(k,k+m,cmp);
                for(int i=0;i<m;i++)
                    printf("%d",k[i].vis);
                printf("
    ");
            }else
                printf("impossible
    ");
        }
        return 0;
    }
    H

    I:优先比较前缀字母,相同前缀的话,后缀越长,字典序越大,暴力找片段,ans数组存储答案,每次加进一个能使字典序最大的字母。

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<math.h>
    #include<string>
    #include<map>
    #include<queue>
    #include<stack>
    #include<set>
    #include<ctime>
    #define ll long long
    #define inf 0x3f3f3f3f
    const double pi=3.1415926;
    const double eps=1e-9;
    using namespace std;
     
     
    char s[1005];
    char ans[1005];
    int cnt;
    int n;
     
     
    bool check(int a){//起始位置
        bool flag=true;
        for(int i=1;i<=cnt;i++){
            if( a+i-1<n && ans[i]==s[a+i-1] ){
               // printf("check if  i=%d a+i-1=%d n=%d
    ",i,a+i-1,n);
            }else{
                flag=false;
            }
        }
        return flag;
    }
     
    int main()
    {
        scanf("%s",s);
        n=strlen(s);
        char maxx=s[0];
        for(int i=0;i<n;i++){
            if(s[i]>maxx)
                maxx=s[i];
        }
        ans[1]=maxx;//先放一个最大的,后续检查前缀相同,每次添加一个最大的字母
        cnt=1;
        bool flag=true;
        while(flag){
            flag=false;
            for(int i=0;i<n;i++)
            {
                if(s[i]==ans[1] && check(i))
                {//第一次只有1
                    if(i+cnt<n && ans[cnt+1]<s[i+cnt])
                        ans[cnt+1]=s[i+cnt],flag=true;
                }
            }
            if(flag)
                cnt++;
        }
        for(int i=1;i<=cnt;i++)
            printf("%c",ans[i]);
        printf("
    ");
        return 0;
    }
    I

    J:最大-最小

  • 相关阅读:
    Apache、IIS、Nginx等绝大多数web服务器,都不允许静态文件响应POST请求
    转载:Struts2+Jquery实现ajax并返回json类型数据
    div 添加滚动条
    jsp页面 如何通过el表达式获取request属性值
    【转】通过Hibernate将数据 存入oracle数据库例子
    jsp 中 有没有类似java if else语句
    IDEA使用(一)
    Git进阶(二)
    JS语法记录
    Debian之MySQL
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/12552599.html
Copyright © 2011-2022 走看看