牛客练习赛23

A托米的赌球

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

题目描述

紧张刺激的世界杯正在进行中(在托米的世界线里),欧洲人托米沉迷于赌球无法自拔。
托米的口袋里有 100 元,50元,20元,10元,5元,2元,1元的纸币,50分,20分,10分,5分,2分,1分的硬币各无限个。
托米计划买下几注 a 元 b 分的彩票,他希望能支出的纸票数量和硬币数量之和最小,他希望你帮助他完成这个任务。同时由于彩票亭不支持找零,托米希望他的支出恰好等于 a 元 b 分

输入描述:

第一行输入一个正整数 T下面 T 行每行两个整数 a,b

输出描述:

每行输出 13 个正整数 n1 ...n13, 对应题面顺序给出最小化支出纸票数量和硬币数量之和的情况下,每种货币的使用次数,如果有多种方案,输出字典序最大的一种,注意这里字典序是依次比较n1到n13,而不是简单的把 13 个正整数拼接在一起

示例1

输入

复制

2
1 5
2 4

输出

复制

0 0 0 0 0 0 1 0 0 0 1 0 0
0 0 0 0 0 1 0 0 0 0 0 2 0

备注:

T=100,0≤ a≤ 109, 0≤ b<100

题解:水题,贪心

#include<stdio.h>
#include<string.h>
#include<map>
#include<algorithm>
using namespace std;
int aa[]={100,50,20,10,5,2,1};
int bb[]={50,20,10,5,2,1};
int main(){
    int t,a,b;
    scanf("%d",&t);
    while(t--){
        int m1[105]={0},m2[105]={0};
        scanf("%d %d",&a,&b);
        for(int i=0;i<=6;i++){
            while(a>=aa[i]){
                m1[aa[i]]++;
                a-=aa[i];
            }
        }
        for(int i=0;i<=5;i++){
            while(b>=bb[i]){
                m2[bb[i]]++;
                b-=bb[i];
            }
        }
        printf("%d %d %d %d %d %d %d %d %d %d %d %d %d\n",m1[100],m1[50],m1[20],m1[10],m1[5],m1[2],m1[1],m2[50],m2[20],m2[10],m2[5],m2[2],m2[1]);
    }
    return 0;
}
B托米的划分

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

题目描述

欧洲人托米非常喜欢数字,他经常在空闲时玩下面的游戏
对于一个数字 n, 托米会随性选中一个数 p, (1 < p <=  n), 将 n 拆分成 ,v=n-u,并对 u,v 重复这个过程,直到他有了 n 个 1
1317 为了挑战托米,在每次托米进行划分时,会给托米奖励 u * v 的分数,托米希望你能帮他最大化他的得分。

输入描述:

第一行一个正整数 T下面 T 行每行一个正整数 n

输出描述:

对于每组数据,输出托米的最大得分

示例1

输入

复制

1 5

输出

复制

10

备注:

T≤ 104, n≤ 109

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
int main(){
    int t,n;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        ll ans=1ll*(n+1)*n/2;
        printf("%lld\n",ans-n);
    }
    return 0;
}
D托米的咒语

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

题目描述

托米没有完成上一个任务,准备施展黑魔法推倒 1317

黑魔法咒语被描述为一个 长为 n 的,仅包含小写英文字母 'a'...'i' 的字符串,在托米所在的星球,魔法造成的每次有效伤害都是来自他的一个子序列,对于每一个 'a'... 'i' 的排列(共 9! 种),若作为咒语的子序列出现, 就会造成 1 的伤害

而咒语的总伤害为所有 'a'... 'i' 的排列造成的伤害值之和,托米能打出多少点的伤害,是否能击败 1317 呢?

输入描述:

一行输入一个字符串 s

输出描述:

一行输出一个数,表示伤害值

示例1

输入

复制

aabcdefghi

输出

复制

1

备注:

|s| ≤  3000

题解:求 abcdefghi 的全排列在 S 串中出现的种类数,用 vector 记录每个字母出现的位置(最后一位都是一个比所有位置数大               的 数),在每次全排列后,一次比较对应的位置优先顺序是否符合。

​
///  AC 代码:
#include<stdio.h>
#include<string.h>
#include<vector>
#include<stdlib.h>
#include<algorithm>
using namespace std;
char s[3005];
vector<int>v[10];
char a[]={'a','b','c','d','e','f','g','h','i'};
int main(){
    scanf(" %s",s);
    int len=strlen(s);
    for(int i=0;i<len;i++){
        v[s[i]-'a'].push_back(i);
    }
    for(int i=0;i<9;i++){
        v[i].push_back(len);  //  很重要
    }
    int ans=0;
    do{
        int leap=0,h=0;
        for(int i=0;i<9;i++){    用二分比较快
            h=*lower_bound(v[a[i]-'a'].begin(),v[a[i]-'a'].end(),h);
            if(h==len){
                leap=1;
                break;
            }
        }
        if(!leap)
            ans++;
    }while(next_permutation(a,a+9));
    printf("%d\n",ans);
    return 0;
}



/ 超时代吗:
#include<stdio.h>
#include<string.h>
#include<vector>
#include<stdlib.h>
#include<algorithm>
using namespace std;
char s[3005];
vector<int>v[10];
char a[]={'a','b','c','d','e','f','g','h','i'};
int main(){
    scanf(" %s",s);
    int len=strlen(s);
    for(int i=0;i<len;i++){
        v[s[i]-'a'].push_back(i);
    }
    int ans=0;
    do{
        int flag=0;
        for(int i=1;i<9;i++){
            int k=i-1;
            int leap=0;
            for(int j=0;j<v[a[i]-'a'].size();j++){
                int leap1=0;
                for(int l=0;l<v[a[k]-'a'].size();l++){
                    if(v[a[i]-'a'][j]>v[a[k]-'a'][l]){
                        leap1=1;
                        break;
                    }
                }
                if(leap1){
                    leap=1;
                    break;
                }
            }
            if(!leap){
                flag=1;
                break;
            }
        }
        if(!flag)
            ans++;
    }while(next_permutation(a,a+9));
    printf("%d\n",ans);
    return 0;
}

​

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值