牛客练习赛13

15 篇文章 0 订阅
10 篇文章 0 订阅

A:找一下4的个数还是7的个数多,如果7多就输出7否则输入4,两者都没有就输出-1

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstdio>
#include<cmath>
#include<set>
#include<map>
#include<cstdlib>
#include<ctime>
#include<stack>
using namespace std;
#define mes(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(i = a; i <= b; i++)
#define dec(i,a,b) for(i = b; i >= a; i--)
#define fi first
#define se second
#define ls rt<<1
#define rs rt<<1|1
#define mid (L+R)/2
#define lson ls,L,mid
#define rson rs,mid+1,R
typedef double db;
typedef long long int ll;
typedef pair<int,int> pii;
typedef unsigned long long ull;
const int mx = 1e5+5;
const int x_move[] = {1,-1,0,0,1,1,-1,-1};
const int y_move[] = {0,0,1,-1,1,-1,1,-1};
int n,m;
char str[mx];
int vis[10];
int main(){
    int t,q,ca = 1;
    while(scanf("%s",str)!=EOF){
        memset(vis,0,sizeof(vis));
        for(int i = 0; str[i]; i++)
            vis[str[i]-'0']++;
        if(vis[7]||vis[4]){
            if(vis[7]>vis[4])
                puts("7");
            else
                puts("4");
        }
        else{
            puts("-1");
        }
    }
    return 0;
}

B:打表算出所有的幸运数字然后找到第一个大于等于l的数一直扫到大于r即可

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstdio>
#include<cmath>
#include<set>
#include<map>
#include<cstdlib>
#include<ctime>
#include<stack>
using namespace std;
#define mes(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(i = a; i <= b; i++)
#define dec(i,a,b) for(i = b; i >= a; i--)
#define fi first
#define se second
#define ls rt<<1
#define rs rt<<1|1
#define mid (L+R)/2
#define lson ls,L,mid
#define rson rs,mid+1,R
typedef double db;
typedef long long int ll;
typedef pair<int,int> pii;
typedef unsigned long long ull;
const int mx = 1e5+5;
const int x_move[] = {1,-1,0,0,1,1,-1,-1};
const int y_move[] = {0,0,1,-1,1,-1,1,-1};
int n,m;
ll a[mx];
void dfs(ll x){
    if(x>1e11)
        return;
    a[n++] = x;
    dfs(x*10+4);
    dfs(x*10+7);
}
int main(){
    int t,q,ca = 1;
    n = 0;
    dfs(0);
    sort(a,a+n);
    ll l,r;
    while(scanf("%lld%lld",&l,&r)!=EOF){
        int k = lower_bound(a,a+n,l)-a;
        ll ans = 0;
        ans += (a[k]-l+1)*a[k];
        for(;a[k]<=r;k++){
            ans += (a[k+1]-a[k])*a[k+1];
        }
        ans -= (a[k]-r)*a[k];
        printf("%lld\n",ans);
    }
    return 0;
}

C:从左往右扫一遍如果出现447或者477并且第一个4是在奇数位会一直死循环变来变去447 477 447

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstdio>
#include<cmath>
#include<set>
#include<map>
#include<cstdlib>
#include<ctime>
#include<stack>
using namespace std;
#define mes(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(i = a; i <= b; i++)
#define dec(i,a,b) for(i = b; i >= a; i--)
#define fi first
#define se second
#define ls rt<<1
#define rs rt<<1|1
#define mid (L+R)/2
#define lson ls,L,mid
#define rson rs,mid+1,R
typedef double db;
typedef long long int ll;
typedef pair<int,int> pii;
typedef unsigned long long ull;
const int mx = 1e5+5;
const int x_move[] = {1,-1,0,0,1,1,-1,-1};
const int y_move[] = {0,0,1,-1,1,-1,1,-1};
int n,m;
char str[mx];
int main(){
    int t,q,ca = 1;
    int n,k;
    while(scanf("%d%d",&n,&k)!=EOF){
        scanf("%s",str);
        for(int i = 0; k&&i < n; i++){
            if(i%2 == 0){
                if(str[i]=='4'&&str[i+1]=='7'&&str[i+2]=='7'){
                    if(k&1)
                        str[i+1]='4';
                    break;
                }
                if(str[i]=='4'&&str[i+1]=='4'&&str[i+2]=='7'){
                    if(k&1)
                        str[i+1]='7';
                    break;
                }
            }
            if(str[i]=='4'&&str[i+1]=='7'){
                k--;
                if(i&1)
                    str[i]='7';
                else
                    str[i+1]='4';
            }
        }
        puts(str);
    }
    return 0;
}

D:康拓展开,因为阶数一大就肯定大于1e9所以我们只要求n-m+1到这些数的排列即可m表示m!>=k的时候其他的数字都在原来的位置,如果K>n!那么肯定不存在排列特判一下即可

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstdio>
#include<cmath>
#include<set>
#include<map>
#include<cstdlib>
#include<ctime>
#include<stack>
using namespace std;
#define mes(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(i = a; i <= b; i++)
#define dec(i,a,b) for(i = b; i >= a; i--)
#define fi first
#define se second
#define ls rt<<1
#define rs rt<<1|1
#define mid (L+R)/2
#define lson ls,L,mid
#define rson rs,mid+1,R
typedef double db;
typedef long long int ll;
typedef pair<int,int> pii;
typedef unsigned long long ull;
const int mx = 1e5+5;
const int x_move[] = {1,-1,0,0,1,1,-1,-1};
const int y_move[] = {0,0,1,-1,1,-1,1,-1};
ll a[mx];
ll fac[mx];
int t;
ll m;
void dfs(ll x){
    if(x>1e11)
        return;
    a[t++] = x;
    dfs(x*10+4);
    dfs(x*10+7);
}
vector<ll>v;
vector<ll>s;
void decantor(ll x,ll n){
    for(int i = 1; i <= m; i++)
        v.push_back(n-i+1);
    x--;
    sort(v.begin(),v.end());
    for(int i = m; i >= 1; i--){
        ll r = x%fac[i-1];
        ll t = x/fac[i-1];
        x = r;
        sort(v.begin(),v.end());
        s.push_back(v[t]);
        v.erase(v.begin()+t);
    }
}
int main(){
    int q,ca = 1;
    ll n,k;
    dfs(0);
    sort(a,a+t);
    fac[0] = 1;
    ll x = 1e15;
    for(int i = 1; i < mx; i++){
        if(x/i<fac[i-1]){
            q = i;
            break;
        }
        fac[i] = fac[i-1]*i;
    }
    while(scanf("%lld%lld",&n,&k)!=EOF){
        s.clear();
        v.clear();
        if(n<18)
            if(k>fac[n])
                puts("-1");
        m = upper_bound(fac+1,fac+q,k)-fac;
        ll ans = 0;
        if(n>m){
            ll x = n-m+1;
            ans = upper_bound(a,a+t,x)-a;
            ans--;
        }
        decantor(k,n);
        for(int i = 0; i < s.size(); i++){
//          cout<<s[i]<<endl;
            ll p = n-m+1+i;
            int k = lower_bound(a,a+t,p)-a;
            if(a[k]==p){
                int z = lower_bound(a,a+t,s[i])-a;
                if(a[z]==s[i])
                    ans++;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

E:因为要求距离原点最远的点,所以我们要跑两边dp一遍是使得修改n条指令后使得值最大,一个最小,接着我们用三维dp表示第一w维表示向左向右,二维表示修改了i条指令,三维表示到达了第几条指令所以dp的转移方程为:

                 if (str[j]== 'F' ){
                     dp[0][i][j] = max(dp[1][i-1][j-1],dp[0][i][j-1]+1);
                     dp[1][i][j] = max(dp[0][i-1][j-1],dp[1][i][j-1]-1);
                 }
                 else {
                     dp[0][i][j] = max(dp[1][i][j-1],dp[0][i-1][j-1]+1);
                     dp[1][i][j] = max(dp[0][i][j-1],dp[1][i-1][j-1]-1);
                 }

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstdio>
#include<cmath>
#include<set>
#include<map>
#include<cstdlib>
#include<ctime>
#include<stack>
using namespace std;
#define mes(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(i = a; i <= b; i++)
#define dec(i,a,b) for(i = b; i >= a; i--)
#define fi first
#define se second
#define ls rt<<1
#define rs rt<<1|1
#define mid (L+R)/2
#define lson ls,L,mid
#define rson rs,mid+1,R
typedef double db;
typedef long long int ll;
typedef pair<int,int> pii;
typedef unsigned long long ull;
const int mx = 1e5+5;
const int inf = 0x3f3f3f3f;
const int x_move[] = {1,-1,0,0,1,1,-1,-1};
const int y_move[] = {0,0,1,-1,1,-1,1,-1};
int n,m;
int dp[2][55][105];
char str[mx];
int main(){
    int t,q,ca = 1;
    while(scanf("%s",str+1)!=EOF){
        scanf("%d",&n);
        m = strlen(str+1);
        for(int i = 0; i <= n; i++)
            for(int j = 0; j <= m; j++)
                dp[0][i][j] = dp[1][i][j] = -inf;
        t = 0;
        dp[0][0][0] = 0;
        for(int i = 1; i <= m; i++){
            if(str[i]=='F'){
                if(t == 0)
                    dp[t][0][i] = dp[t][0][i-1]+1;
                if(t == 1)
                    dp[t][0][i] = dp[t][0][i-1]-1;
            }
            else{
                t ^= 1;
                dp[t][0][i] = dp[t^1][0][i-1];
            }
        }
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++){
                if(str[j]=='F'){
                    dp[0][i][j] = max(dp[1][i-1][j-1],dp[0][i][j-1]+1);
                    dp[1][i][j] = max(dp[0][i-1][j-1],dp[1][i][j-1]-1);
                }
                else{
                    dp[0][i][j] = max(dp[1][i][j-1],dp[0][i-1][j-1]+1);
                    dp[1][i][j] = max(dp[0][i][j-1],dp[1][i-1][j-1]-1);
                }
            }
        int ans = 0;
        if(dp[0][n][m]>1000-inf)
            ans = max(abs(dp[0][n][m]),ans);
        if(dp[1][n][m]>1000-inf)
            ans = max(abs(dp[1][n][m]),ans);
        memset(dp,inf,sizeof(dp));
        t = 0;
        dp[0][0][0] = 0;
        for(int i = 1; i <= m; i++){
            if(str[i]=='F'){
                if(t == 0)
                    dp[t][0][i] = dp[t][0][i-1]+1;
                if(t == 1)
                    dp[t][0][i] = dp[t][0][i-1]-1;
            }
            else{
                t ^= 1;
                dp[t][0][i] = dp[t^1][0][i-1];
            }
        }
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++)
                if(str[j]=='F'){
                    dp[0][i][j] = min(dp[1][i-1][j-1],dp[0][i][j-1]+1);
                    dp[1][i][j] = min(dp[0][i-1][j-1],dp[1][i][j-1]-1);
                }
                else{
                    dp[0][i][j] = min(dp[1][i][j-1],dp[0][i-1][j-1]+1);
                    dp[1][i][j] = min(dp[0][i][j-1],dp[1][i-1][j-1]-1);
                }
        if(dp[0][n][m]<inf-1000)
            ans = max(ans,abs(dp[0][n][m]));
        if(dp[1][n][m]<inf-1000)
            ans = max(ans,abs(dp[1][n][m]));
        printf("%d\n",ans);
    }
    return 0;
}

F:用4个set数组表示在第x个横坐标上,y个纵坐标上,斜向上,斜向下的上面对应的x坐标,y坐标,然后一个一个点遍历是否有大于他的点或者小于他的点

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstdio>
#include<cmath>
#include<set>
#include<map>
#include<cstdlib>
#include<ctime>
#include<stack>
using namespace std;
#define mes(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(i = a; i <= b; i++)
#define dec(i,a,b) for(i = b; i >= a; i--)
#define fi first
#define se second
#define ls rt<<1
#define rs rt<<1|1
#define mid (L+R)/2
#define lson ls,L,mid
#define rson rs,mid+1,R
typedef double db;
typedef long long int ll;
typedef pair<int,int> pii;
typedef unsigned long long ull;
const int mx = 1e5+5;
const int x_move[] = {1,-1,0,0,1,1,-1,-1};
const int y_move[] = {0,0,1,-1,1,-1,1,-1};
int n,m;
struct node{
    int x,y;
}a[mx];
set<int>st[4][2*mx];
int ans[10];
int search(int d,int x,int y){
    int k = 0;
    if(st[d][x].lower_bound(y)!=st[d][x].begin())
        k++;
    if(st[d][x].upper_bound(y)!=st[d][x].end())
        k++;
    return k;
}
int main(){
    int t,q,ca = 1;
    while(scanf("%d%d",&n,&m)!=EOF){
        memset(ans,0,sizeof(ans));
        for(int i = 1; i <= 2*n; i++)
            for(int j = 0; j < 4; j++)
                st[j][i].clear();
        for(int i = 1; i <= m; i++){
            scanf("%d%d",&a[i].x,&a[i].y);
            st[0][a[i].x].insert(a[i].y);
            st[1][a[i].y].insert(a[i].x);
            st[2][a[i].x+a[i].y].insert(a[i].x);
            st[3][a[i].y-a[i].x+n].insert(a[i].x);
        }
        int k;
        for(int i = 1; i <= m; i++){
            k = 0;
            k += search(0,a[i].x,a[i].y);
            k += search(1,a[i].y,a[i].x);
            k += search(2,a[i].x+a[i].y,a[i].x);
            k += search(3,a[i].y-a[i].x+n,a[i].x);
            ans[k]++;
        }
        for(int i = 0; i <= 8; i++)
            printf("%d%c",ans[i],i==8?'\n':' ');
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值