牛客练习赛23CD

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

题目描述 
托米完成了1317的上一个任务,十分高兴,可是考验还没有结束
说话间1317给了托米 n 个自然数 a1... an, 托米可以选出一些带回家,但是他选出的数需要满足一些条件
设托米选出来了k 个数 b1,b2... bk, 设这个数列 b 的给值为 b 中所有数按位与的结果,如果你能找到一个整除 b 的最大的 2v,(v≥ 0), 则设定 v 为这个数列的给价,如果不存在这样的 v,则给价值为 -1, 1317 希望托米在最大化给价的情况下,最大化 k
输入描述:
第一行输入一个整数 n, 第二行输入 a1...an
输出描述:
第一行输出最大的整数 k, 第二行输出 k 个整数 b1... bk, 按原数列的相对顺序输出 (如果行末有额外空格可能会格式错误)
示例1
输入

复制
5
1 2 3 4 5
输出

复制
2
4 5
备注:
n≤ 105, a1... an < 231

整除2v换成2进制不存在位数小于 2v的最高位,用lowbit返回

#include <iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;
#define ll long long
int a[111111];
int num[111111];
int main()
{
   int n;
   scanf("%d",&n);
   for(int i=1;i<=n;i++)
    scanf("%d",&a[i]);
    long long int ans=0;
   for(int i=0;i<=31;i++)
   ans=ans|(1ll )<<i;
   int sz=0;
   for(int i=31;i>=0;i--)
   {
       ll p=ans; sz=0;
       for(int j=1;j<=n;j++)
       {
         if(1ll<<i&a[j])
            {p=p&a[j];
            num[sz++]=j;
            }
       }
     if((p&(-p))>=(1ll<<i))
        break;
   }
   cout<<sz<<endl;
   for(int i=0;i<sz;i++)
   {
       if(i)
        cout<<" ";
    cout<<a[num[i]];
   }
   cout<<endl;
    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

  保存位子,二分查找

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
char a[3010];
vector<int >g[200];
int b[9];
int main()
{
    cin>>a;
    int t=strlen(a);
    for(int i=0;i<t;i++)
    {
        g[a[i]-'a'].push_back(i);
    }
    for(int i=0;i<9;i++) b[i]=i;
    int ans=0;
    do
    {
        int flag=1;
        int now=-1;
        for(int i=0;i<9;i++)
        {
             
            if(g[b[i]].size()==0||g[b[i]][g[b[i]].size()-1]<=now)
            {
                flag=0;
                break;
            }
            int to=lower_bound(g[b[i]].begin(),g[b[i]].end(),now) - g[b[i]].begin();
            now=g[b[i]][to];
        }
        if(flag)
            ans++;
         
         
    }while(next_permutation(b,b+9));
    cout<<ans<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/2014slx/p/9381105.html