牛客练习赛13

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

幸运数字Ⅰ
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

定义一个数字为幸运数字当且仅当它的所有数位都是4或者7。
比如说,47、744、4都是幸运数字而5、17、467都不是。
现在,给定一个字符串s,请求出一个字符串,使得:
1、它所代表的整数是一个幸运数字;
2、它非空;
3、它作为s的子串(不是子序列)出现了最多的次数(不能为0次)。
请求出这个串(如果有多解,请输出字典序最小的那一个)。

输入描述:

串s(1 <= |s| <= 50)。s只包含数字字符,可以有前导零。

输出描述:

一个串表示答案。
无解输出-1。
示例1

输入

047

输出

4
示例2

输入

16

输出

-1

虽然是找子序列,但是你想啊,要出现次数最多,那么一定是4和7

所以答案就只有4和7,分情况讨论下

#include<bits/stdc++.h>
using namespace std;
string str;
int main()
{
    ios::sync_with_stdio(false);
    cin>>str;
    int sum1=0,sum2=0;
    for(int i=0;str[i];i++)
    {
        if(str[i]=='4')
            sum1++;
        if(str[i]=='7')
            sum2++;
    }
    if(sum1==0&&sum2==0)
    {
        cout<<-1;
        return 0;
    }
    if(sum1==sum2)
        cout<<4;
    else if(sum1>sum2)
        cout<<4;
    else
        cout<<7;
    return 0;
}

可以写短点的啊

#include<bits/stdc++.h>
using namespace std;
string s;
int a[256];
int main()
{
    ios::sync_with_stdio(false);
    cin>>s;
    for(int i=0;s[i];i++)a[s[i]]++;
    if(!a['4']&&!a['7'])
        cout<<-1;
    else if(a['4']>=a['7'])
        cout<<4;
    else cout<<7;
    return 0;
}

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

幸运数字Ⅱ
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

定义一个数字为幸运数字当且仅当它的所有数位都是4或者7。
比如说,47、744、4都是幸运数字而5、17、467都不是。
定义next(x)为大于等于x的第一个幸运数字。给定l,r,请求出next(l) + next(l + 1) + ... + next(r - 1) + next(r)。

输入描述:

两个整数l和r (1 <= l <= r <= 1000,000,000)。

输出描述:

一个数字表示答案。
示例1

输入

2 7

输出

33
示例2

输入

7 7

输出

7

BFS生成这个序列,然后去统计每个区段是多少个

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
ll luck[N];
int cnt,a[2]={4,7};
struct T
{
    ll x,step;
} first,cur,nxt;
void bfs()
{
    queue<T>q;
    first={0,0};
    q.push(first);
    while(!q.empty())
    {
        cur=q.front();
        q.pop();
        if(cur.step>9)
        {
            return;
        }
        for(int i=0; i<2; i++)
        {
            nxt.x=cur.x*10+a[i];
            nxt.step=cur.step+1;
            q.push(nxt);
            luck[++cnt]=nxt.x;
        }
    }
}
int main()
{
    bfs();
    ll l,r;
    cin>>l>>r;
    ll tmp1,tmp2;
    tmp1=-1;
    ll sum=0;
    for(int i=0;i<10000;i++)
    {
        if(luck[i]>=l&&tmp1==-1)
        {
            tmp1=i;
        }
        if(luck[i]>=r)
        {
            tmp2=i;
            break;
        }
    }
    for(int i=tmp1;i<=tmp2;i++)
    {
        sum+=(min(luck[i],r)-l+1)*luck[i];
        l=luck[i]+1;
    }
    cout<<sum;
    return 0;
}

下面的循环还可以这样缩短,其实相当于用0 1去模拟4和7,bfs出序列就不用排序,dfs的需要sort一下

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
ll a[N];
int cnt,b[2]={4,7};
struct T
{
    ll x,step;
} first,cur,nxt;
void bfs()
{
    queue<T>q;
    first={0,0};
    q.push(first);
    while(!q.empty())
    {
        cur=q.front();
        q.pop();
        if(cur.step>9)return;
        for(int i=0; i<2; i++)
            nxt.x=cur.x*10+b[i],nxt.step=cur.step+1,q.push(nxt),a[++cnt]=nxt.x;
    }
}
int main()
{
    bfs();
    ll l,r;
    cin>>l>>r;
    ll sum=0,now=l,pos=0;
    while(now<=r)
    {
        while(a[pos]<now) ++pos;
        sum+=a[pos]*(min(r,a[pos])-now+1);
        now=a[pos]+1;
    }
    cout<<sum;
    return 0;
}

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

幸运数字Ⅲ
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

定义一个数字为幸运数字当且仅当它的所有数位都是4或者7。
比如说,47、744、4都是幸运数字而5、17、467都不是。
假设现在有一个数字d,现在想在d上重复k次操作。
假设d有n位,用d1,d2,...,dn表示。
对于每次操作,我们想要找到最小的x (x < n),使得dx=4并且dx+1=7。
如果x为奇数,那么我们把dx和dx+1都变成4;
否则,如果x为偶数,我们把dx和dx+1都变成7;
如果不存在x,那么我们不做任何修改。
现在请问k次操作以后,d会变成什么样子。

输入描述:

第一行两个整数n,k表示d的长度和操作次数。
第二行一个数表示d。数据保证不存在前导零。
1 <= n <= 100,000
0 <= k <= 1000,000,000

输出描述:

一个数字表示答案。
示例1

输入

7 4
4727447

输出

4427477
示例2

输入

4 2
4478

输出

4478

有特殊的数字,447和477会循环,其他的也不会回退,枚举这两个就可以了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
string s;
int main()
{
    int n,k;
    cin>>n>>k>>s;
    for(int i=1; s[i]&&k; i++)
    {
        if(s[i-1]=='4'&&s[i]=='7')
        {
            if(i-1!=0&&s[i-2]=='4'&&i%2==0)
            {
                if(k&1)s[i-1]='7';
                k=0;
            }
            else if(s[i+1]=='7'&&i%2==1)
            {
                if(k&1)s[i]='4';
                k=0;
            }
            else
            {
                k--;
                if(i&1)s[i]='4';
                else s[i-1]='7';
            }
        }
    }
    cout<<s;
    return 0;
}

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

m皇后
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

在一个n*n的国际象棋棋盘上有m个皇后。
一个皇后可以攻击其他八个方向的皇后(上、下、左、右、左上、右上、左下、右下)。
对于某个皇后,如果某一个方向上有其他皇后,那么这个方向对她就是不安全的。
对于每个皇后,我们都能知道她在几个方向上是不安全的。

现在我们想要求出t0,t1,...,t8,其中ti表示恰有i个方向是"不安全的"的皇后有多少个。

输入描述:

第一行两个整数n,m表示棋盘大小和皇后数量。
接下来m行每行两个整数ri,ci表示皇后坐标。
1 <= n, m <= 100,000
1 <= r
i
, c
i
<= n
数据保证没有皇后在同一个位置上。

输出描述:

一行九个整数表示答案。
空格隔开,结尾无空格
示例1

输入

8 4
4 3
4 8
6 5
1 6

输出

0 3 0 1 0 0 0 0 0
示例2

输入

10 3
1 1
1 2
1 3

输出

0 2 1 0 0 0 0 0 0

这也算模拟吧,找到每一行最左边的点最右边的点,每一列最上面的点,最下面的点,还有四个方向,然后判断这个点在他的什么方向,它是的话就有,不是的话就没有

#include<bits/stdc++.h>
using namespace std;
vector<pair<int,int> > v;
const int N=1e5+5,INF=1e9+7;
int minnx[2*N];
int minny[2*N];
int minnd[2*N];
int minnb[2*N];
int maxxx[N];
int maxxy[N];
int maxxd[2*N];
int maxxb[2*N];
int s[10];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<2*N;i++)
        minnx[i]=INF,minny[i]=INF,minnd[i]=INF,minnb[i]=INF;
    for(int i=0,x,y;i<m;i++)
    {
        scanf("%d%d",&x,&y);
        v.push_back(make_pair(x,y));
        minnx[x]=min(minnx[x],y);
        maxxx[x]=max(maxxx[x],y);
        minny[y]=min(minny[y],x);
        maxxy[y]=max(maxxy[y],x);
        minnd[N+y-x]=min(minnd[N+y-x],x);
        maxxd[N+y-x]=max(maxxd[N+y-x],x);
        minnb[x+y]=min(minnb[x+y],x);
        maxxb[x+y]=max(maxxb[x+y],x);
    }
    for(int i=0;i<m;i++)
    {
        int sum=0,nx=v[i].first,ny=v[i].second;
        if(nx>minny[ny])
            sum++;
        if(nx<maxxy[ny])
            sum++;
        if(ny>minnx[nx])
            sum++;
        if(ny<maxxx[nx])
            sum++;
        if(nx>minnd[N+ny-nx])
            sum++;
        if(nx<maxxd[N+ny-nx])
            sum++;
        if(nx>minnb[nx+ny])
            sum++;
        if(nx<maxxb[nx+ny])
            sum++;
        s[sum]++;
    }
    cout<<s[0];
    for(int i=1;i<9;i++)cout<<" "<<s[i];
    return 0;
}

 

posted @ 2018-03-17 07:36  暴力都不会的蒟蒻  阅读(520)  评论(0编辑  收藏  举报