• 0608模拟算法试题


    6.8模拟算法试题

    测试说明

    4个题目,3.5小时

    以姓名命名文件夹,下存4个文件,分别命名。

    1、洛谷  P1010 幂次方

    题目描述

    任何一个正整数都可以用2的幂次方表示。例如

        137=2^7+2^3+2^0         

    同时约定方次用括号来表示,即a^b 可表示为a(b)。

    由此可知,137可表示为:

        2(7)+2(3)+2(0)

    进一步:7= 2^2+2+2^0 (2^1用2表示)

        3=2+2^0   

    所以最后137可表示为:

        2(2(2)+2+2(0))+2(2+2(0))+2(0)

    又如:

        1315=2^10 +2^8 +2^5 +2+1

    所以1315最后可表示为:

        2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)

    输入输出格式

    输入格式:

    一个正整数n(n≤20000)。

    输出格式:

    符合约定的n的0,2表示(在表示中不能有空格)

    输入输出样例

    输入样例#1:

    1315

    输出样例#1:

    2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)
    /*
    先把所求转化为2进制,回溯模拟,注意判断‘+’是否该加
    详见代码 
    */
    #include<cstdio>
    #include<iostream>
    using namespace std;
    long long n;
    void search(long long x){
        int i=0,j=0;int a[101];
        if(!x) {cout<<0;return ;}
        while(x>0){
            if(x%2==1) a[j++]=i;//按位异或符 2^0->++ 转换二进制 
            x>>=1;
            i++;    
        }
        for(i=j-1;i>=0;i--){
            if(a[i]==1) cout<<"2";
            else{
                cout<<"2(";
                search(a[i]);//高位继续变低 直到<2 
                cout<<")";
                
            } 
            if(i!=0)cout<<"+";
        }
    }
    int main()
    {
        long long n;
        cin>>n;
        search(n);
        return 0;
     } 

    2、codevs 1432 总数统计

    题目描述 Description

    给出n个数,统计两两之和小于k的方案数之和。

    输入描述 Input Description

    第一行一个数n,表示数字的个数;
    第二行到第n + 1行,每行一个不超过2,000,000,000的数k;
    第n + 2行一个数m,表示m个问题;
    第n + 3行到第n + m + 2行,每行一个数m,询问表示n中两两组合不超过m的组
    合的个数;

    输出描述 Output Description

    输出m行,每行对应一个答案

    样例输入 Sample Input

    3

    1

    2

    3

    2

    2

    3

    样例输出 Sample Output

    0

    1

    数据范围及提示 Data Size & Hint

    30%的数据1 ≤ n ≤ 100, 1 ≤ m ≤ 50, k ≤ 2000;
    100%的数据 1 ≤ n ≤ 10000, 1 ≤ m ≤ 100, k ≤ 2,000,000,000;

    /*
    二分答案+sort     注意数据超int,要用long long 
    思路:sort有序后二分
    找一个对ans有贡献的数x(即<=k/2)
    二分k-x的下界 那么之前的数与该数组合均可以构成一组合
    */
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    long long num[101000],ans,n,m,k;
    long long div(long long x){
        long long l=1,r=n+1;
        while(r-l>1){
            long long mid=(l+r>>1);
            if(num[mid]<=x) l=mid;
            else r=mid;
        }
        return l;
    }
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>num[i];
        }
        sort(num+1,num+n+1);
        cin>>m;
        while(m--){
            cin>>k;ans=0;
            for(int i=1;num[i]<=k/2;i++){
                long long x=div(k-num[i]);
                if(x>i) ans+=x-i;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }

    3、2835 挖金币游戏

    题目描述 Description

    这天,小X幸运地获得了一次进行挖金币游戏的机会,规则如下:

        在一个N*N的矩形里,有N*N个边长为1的正方形格子。在游戏中取左下角的格子坐标为(1,1),右上角为(N,N)。在游戏开始前,每一个格子中都会放入一枚金币,而当游戏开始时,每一个格子中的那一枚金币都会进行一次移动,移动后的横、纵坐标值将分别变为原横、纵坐标值每一位上的乘积。当有金币被移动出格子矩形时,将被游戏方收走。小X将被允许选取M个格子,他将获得他所选取的格子中所有的金币,而他对游戏中获得的金币数有一个期望值H。他想知道他最多能获得的金币数能否达到他的期望值。不过金币移动的让人眼花缭乱,小X算不过来了,他找到了你,希望你能用编程解决这个问题。

    输入描述 Input Description

    一行,三个正整数数N、M、H,以空格隔开,意义如题目中所说

    输出描述 Output Description

    一个或两个正整数数,以空格隔开

    若小X最多能获得的金币数能达到期望值(即大于等于),则输出小X最多能获得的金币数以及金币总数能达到期望值的格子数的最小值

    若小X最多能获得的金币数不能达到期望值(即小于),则输出金币数最多的那个格子中的金币数

    样例输入 Sample Input

    17 3 10

    样例输出 Sample Output

    12 3

    数据范围及提示 Data Size & Hint

    对于20%的数据,保证0<M≤N≤100

    对于50%的数据,保证0<M≤N≤2000

    对于70%的数据,保证0<M≤N≤5000

    对于100%的数据,保证0<M≤N≤10000

    举例,(123,456)处的金币将会被移动至(1*2*3,4*5*6)即(6,120)。

    /*解题思路:设f[i][j] 为移动后i,j上的金子数,
    f[i][j]=g[i]*g[j],g[i]是1到n中有多少数会转化为i,
    然后从g*g的二维数组里找最大的M个。
    //高级数据结构STL模拟+读入优化
    //bian()模拟变化*/ 
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #define ll long long
    #define Mo 1000000007
    #define M 500000
    #define pa pair<ll,int>
    using namespace std;
    ll read(){
        register ll x=0,f=1;
        register char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*f;
        
    }
    int n,m;
    ll zui,shu,he,h,f[M];
    int bian(int x){
        int ans=1;
        for(;x;){
              ans*=x%10;
              x/=10;
        }
        return ans;
    }
    int main(){
        n=read();
        m=read();
        h=read();
        for(int i=1;i<=n;i++){
              int a1=bian(i);
              if(a1>=1&&a1<=n)
                 f[a1]++;
        }
        sort(f+1,f+n+1);
        priority_queue<pa,vector<pa>,less<pa> > q;
        for(int i=n;i>=0;i--)
            q.push(make_pair(f[n]*f[i],n));
        for(int i=1;i<=m;i++){
              int p=q.top().second;
              ll p1=q.top().first;
              if(i==1)
                 zui=p1;
              he+=p1;
              if(he>=h&&!shu)
                 shu=i;
            q.pop();
            if(p)
               q.push(make_pair(p1/f[p]*f[p-1],p-1));
        }
        if(shu)
          printf("%lld %lld
    ",he,shu);
        else
          printf("%lld
    ",zui);
        return 0;       
    } 

    4、洛谷P1039 侦探推理

    题目描述

    明明同学最近迷上了侦探漫画《柯南》并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏。游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明明的任务就是找出这个罪犯。接着,明明逐个询问每一个同学,被询问者可能会说:

    证词中出现的其他话,都不列入逻辑推理的内容。

    明明所知道的是,他的同学中有N个人始终说假话,其余的人始终说真。

    现在,明明需要你帮助他从他同学的话中推断出谁是真正的凶手,请记住,凶手只有一个!

    输入输出格式

    输入格式:

    输入由若干行组成,第一行有二个整数,M(1≤M≤20)、N(1≤N≤M)和P(1≤P≤100);M是参加游戏的明明的同学数,N是其中始终说谎的人数,P是证言的总数。接下来M行,

    每行是明明的一个同学的名字(英文字母组成,没有主格,全部大写)。

    往后有P行,每行开始是某个同学的名宇,紧跟着一个冒号和一个空格,后面是一句证词,符合前表中所列格式。证词每行不会超过250个字符。

    输入中不会出现连续的两个空格,而且每行开头和结尾也没有空格。

    输出格式:

    如果你的程序能确定谁是罪犯,则输出他的名字;如果程序判断出不止一个人可能是罪犯,则输出 Cannot Determine;如果程序判断出没有人可能成为罪犯,则输出 Impossible。

    输入输出样例

    输入样例#1:

    3 1 5
    MIKE
    CHARLES
    KATE
    MIKE: I am guilty.
    MIKE: Today is Sunday.
    CHARLES: MIKE is guilty.
    KATE: I am guilty.
    KATE: How are you??

    输出样例#1:

    MIKE

     

    /*
    检查:
    1.记录已确定说谎人数,不说谎人数。
    2. 怎么方便怎么来,不要想着会超时。永远0ms!
    3. 函数返回值的时机。
    处理数据!!:
    1. 全说谎,全不说谎
    2. 名字叫“GUILTY”、“I”、星期几、特别长
    3. 证词一旦不与表中相同,就作废!(正确的证词后面加一点点点废话,你懂的)
    4. 测点怎么没有人叫TODAY?…………
    5 .数据一定要读完。
    其他:
    什么输出时多一个少一个空格神马的一定要注意。
    */
    #include<cstdio>
    #include<cstring>
    #include<map>
    #include<string>
    using namespace std;
    map<string,int>Map;
    char s[105][25][525],name[105][525],ans[105][525],a[25][525];
    int num[105],f[25],n,m,i,j,k,P,Today,flag,now,lie,Len,cnt,T;
    char day[8][25]={"","Monday.","Tuesday.","Wednesday.","Thursday.","Friday.","Saturday.","Sunday."};
    inline int equal(char *s1,char *s2){
        int l1=strlen(s1),l2=strlen(s2);
        if(l1!=l2) return 0;
        for(int i=0;i<l1;i++) 
            if(s1[i]!=s2[i]) 
                return 0;
        return 1;
    }
    inline int check_1(int k){
        if(!equal(s[k][num[k]],"guilty.")||num[k]<3||num[k]>4)
           return 2;
        if(s[k][1][0]!='I'||s[k][1][1]!=''||!equal(s[k][2],"am")) 
           return 2;
        if(num[k]==4) 
           if(!equal(s[k][3],"not")) 
              return 2;
        if(Map[name[k]]==now){
           if(num[k]==3) 
              return 0;
           return 1;
        }
        if(num[k]==3) 
           return 1;
        return 0;
    }
    inline int check_2(int k){
        if(!equal(s[k][num[k]],"guilty.")||num[k]<3||num[k]>4)
           return 2;
        if(!equal(s[k][2],"is")) 
           return 2;
        if(num[k]==4) if(!equal(s[k][3],"not")) 
           return 2;
        if(Map[s[k][1]]==now){
           if(num[k]==3) 
              return 0;
           return 1;
        }
        if(num[k]==3) 
           return 1;
        return 0;
    }
    inline int check_3(int k){
        if(num[k]!=3||!equal(s[k][1],"Today")||!equal(s[k][2],"is"))
           return 2;
        return equal(day[Today],s[k][3])^1;
    }
    inline int work(){
        now=Map[a[P]];
        int res=0,another=0;
        memset(f,0,sizeof(f));
        for(int i=1;i<=m;i++){
            int T1=check_1(i),T2=check_2(i),T3=check_3(i),pre=Map[name[i]];
            if(!T1||!T2||!T3){
                if(f[pre]==2) 
                   return 0;
                f[pre]=1;
            }
            if(T1&1||T2&1||T3&1){
               if(f[pre]==1) return 0;
               f[pre]=2;
            }
        }
        for(int i=1;i<=n;i++)
            if(f[i]==2) res++;
            else if(!f[i]) another++;
        return (res<=lie&&res+another>=lie);
    }
    inline int OK(char ch){return (ch>='A'&&ch<='Z'||ch>='a'&&ch<='z');}
    int main(){
        scanf("%d%d%d",&n,&lie,&m);
        for(i=1;i<=n;i++) scanf("%s",a[i]),Map[a[i]]=i;
        for(i=1;i<=m;i++) {
            scanf("%s",name[i]);name[i][strlen(name[i])-1]='';
            scanf("%s",s[i][num[i]=1]);
            while (OK(s[i][num[i]][strlen(s[i][num[i]])-1])) 
                scanf("%s",s[i][++num[i]]);
        }
        for(P=1;P<=n;P++){
            flag=0;
            for(Today=1;Today<=7&&!flag;Today++) 
                flag=work();
            if(flag) 
               memcpy(ans[++cnt],a[P],sizeof(a[P]));
        }
        if(!cnt) printf("Impossible");
        else if(cnt==1) printf("%s",ans[cnt]);
        else printf("Cannot Determine");
        return 0;
    }
  • 相关阅读:
    iOS开发UITableViewCell的选中时的颜色设置
    NSUserDefaults存储数据
    iOS持久化存储
    ios nil、NULL和NSNull 的使用
    IOS NavigationController Toolbar学习笔记
    一、利用NSUserDefaults进行对短小数据的存和取(自定义对象的存取)。
    使用NSUserDefaults保存用户名和密码
    const与static的区别
    CALayer
    UILocalNotification
  • 原文地址:https://www.cnblogs.com/shenben/p/5570394.html
Copyright © 2020-2023  润新知