牛客练习-哈尔滨理工大学21级新生程序设计竞赛(同步赛)

53 篇文章 0 订阅
9 篇文章 0 订阅

比赛链接:哈尔滨理工大学21级新生程序设计竞赛(同步赛)


前言

昨天python考试没参加,于是乎今天做一做。虽说简单,但真正做起来花了我三个小时,没借助任何外力,包括自己debug,只想说单凭自己做真的不容易即使很简单,自己的问题会被无限放大。一共做了十一个,前十一个。有两道题目意思理解错了(D、K),有点影响心态,先放下去做别的,后来又看发现意思理解错了(会放错误理解的代码);也有没考虑全面的题;也有思维上没想清楚导致wa了,总的来说,记录一下过程。


正文

做这些题感觉有点浪费时间了,简单代码不放了,可以去链接里找到提交后正确的代码,都写的挺简洁的。

A.考试周破防

签到

B.咖啡店

签到

C.kiki和bob玩取石子

博弈论,签到

D.猴王kiki分桃

题意读错,一直90分过不了。。。
n个猴子(包括kiki)都从篮子中拿走恰好一个桃子 草这里理解错了,一拿拿n个,而我以为可以不拿n个

#include <iostream>
#define int long long

using namespace std;

//n个猴子(包括kiki)都从篮子中拿走恰好一个桃子   草这里理解错了

signed main()
{
    int n,l,r;
    cin >> n >> l >> r;
    
    int ans;   //r%n          n-1
    ans = n-1ll;
    
    if(r/n*n < l || r/n*n > r){
        ans = r - r / n * n;
    }
    
    
    cout << ans << endl;
    
    return 0;
}

/*
2 2 2
0

7 13 13
6

2 5 5

4 9 9
3
ans = 1
*/

E.很二的拆分

位运算,签到

F.构造字符串

简单动态规划问题,白书例题.

G.信号之旅

简单问题,分情况讨论即可.

#include <iostream>
#include <cstdio>
#include <cmath>

using namespace std;

int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        int x1,y1,xb,yb,x2,y2;
        
        scanf("%d%d%d%d%d%d",&x1,&y1,&x2,&y2,&xb,&yb);
//         cout << x1 << " " << y1 << " " << x2 << " " << y2 << " " << xb << " " << yb << endl;
        
        int ans = 0;
        if(x1!=x2 && y1!=y2){
            ans = abs(x2-x1) + abs(y2-y1);
        }else if(x1==x2 && y1!=y2){
            if(xb==x1 && ((yb>y1&&yb<y2) || (yb>y2&&yb<y1))){
                ans = abs(y2-y1) + 2;
            }else{
                ans = abs(y2-y1);
            }
        }else if(y1==y2 && x1!=x2){
            if(yb==y1 && ((xb>x1&&xb<x2) || (xb>x2&&xb<x1))){
                ans = abs(x2-x1) + 2;
            }else{
                ans = abs(x2-x1);
            }
        }
        
        printf("%d\n",ans);
    }
    
    
    return 0;
}

H.小球滚动

这里注意题目的意思是两边都能滚落,最短距离即为每个小球距离端点的最短距离的最大值;最大距离为每个小球距离端点的最长距离的最大值。(这里可能有点绕)

I.kiki看球赛

贪心即可。
个人认为这题需要排序,但其实不需要。

J.跳一跳

典型DP问题,背包问题,这里我写的dfs,注意剪枝不然超时。

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

typedef long long ll;

ll ans = 0;
ll n;
ll a[100010];
bool st[100010];      //记录点的到达情况
void dfs(int step){
    if(step>n){
        ans = n;
        return;
    }
    st[step] = 1;
    if(a[step]<=0){
        ans = max(ans,(ll)step);
        return;
    }
    
    for(int i=1;i<=a[step];i++){
        if(st[step+i])    continue;         //如果这个点到达过了
        dfs(step+i);
    }
}

int main()
{
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)    scanf("%lld",&a[i]);
    
    dfs(1);
    
    cout << ans << endl;
    
    return 0;
}

K.Jay的小弟

这题给我整吐了,写了一百多行,发现题意读错了,还有就是别用cin,超时了…日。
对题目误解后的分析代码中有。

// //DP:对于每一个连续的jay、jya、ajy、ayj,yaj,yja有且仅有使用和不使用魔法.

// // ans=max(ans*2,ans+1)
// // 注意到前面的连续jay可能会不适用魔法,越到后面的jay使用魔法的效果越好.
// // 因此只需要枚举前面几个连续jay的情况就可以(使用魔法和不使用魔法)o(n)

// // 第一次出现jay的时候才可能会+1,当且仅当ans=0时.

// #include <iostream>
// #include <cstdio>
// #include <algorithm>
// #include <vector>
// #include <stack>

// using namespace std;

// // 应该从后向前匹配jay串
// // JayJayJJJaaayyyJay

// typedef long long ll;

// const int MOD = 1e9 + 7;

// string s;
// int len;
// // vector<int> vc;
// // stack<int> vc;
// int vc[100000000],top = -1;

// bool check(int k){
// //     if(k+2>len)    return false;
    
//     if((s[k]=='J'&&s[k+1]=='a'&&s[k+2]=='y'))
//         return true;
//     return false;
// }

// int main()
// {
//     cin >> s;
//     len = s.size();
//     s = " " + s;
//     for(int i=len;i>=3;i--){
//         if(check(i-2)){
//             vc[++top] = i-2;
//             i -= 2;
//         }
//     }
    
//     int cnt1 = 0,cnt2 = 0,cnt3 = 0;
//     ll ans = 0;
//     for(int i=1;i<=len;i++){
// //         cout << i << " " << check(i) << endl;
        
//         if(top!=-1 &&vc[top]==i){
//             top--;
//             if(!ans){
//                 ans = (ans + 1)%MOD;
//             }else{
//                 ans = (ans * 2)%MOD;
//             }
            
//             i += 2;
//         }else{
//             if(s[i]=='J')    cnt1++;
//             if(s[i]=='a')    cnt2++;
//             if(s[i]=='y')    cnt3++;
        
//             if(cnt1>=1 && cnt2>=1 && cnt3>=1){
//                 cnt1--;
//                 cnt2--;
//                 cnt3--;
//                 ans = (ans + 1)%MOD;
//             }
//         }
        
// //         cout << "ans=" << ans << endl;
//     }
    
//     cout << ans << endl;
    
//     return 0;
// }

// /*
// if((s[k]=='J'&&s[k+1]=='a'&&s[k+2]=='y')
//       ||(s[k]=='J'&&s[k+1]=='y'&&s[k+2]=='a')
//       ||(s[k]=='a'&&s[k+1]=='J'&&s[k+2]=='y')
//       ||(s[k]=='a'&&s[k+1]=='y'&&s[k+2]=='J')
//       ||(s[k]=='y'&&s[k+1]=='J'&&s[k+2]=='a')
//       ||(s[k]=='y'&&s[k+1]=='a'&&s[k+2]=='J'))
// */


/*
    重写
    题意理解错了.
*/
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

typedef long long ll;

const int MOD = 1e9 + 7;

char s[100000010];
int len;
bool book[100000010];

ll quick_mod(ll a,ll b){
    ll res = 1;
    while(b){
        if(b&1)    res = res * a % MOD;
        b >>= 1;
        a = a*a%MOD;
    }
    
    return res;
}

int main()
{
    scanf("%s",s);
    len = strlen(s);
    
    ll cnt = 0;
    for(int i=len-1;i>=2;i--){
        if(s[i-2]=='J' && s[i-1]=='a' && s[i]=='y'){
            cnt++;
            book[i-2] = 1;
            i -= 2;
        }
    }
    
    int cnt1 = 0,cnt2 = 0,cnt3 = 0;
    for(int i=0;i<len;i++){
        if(book[i]){
            i+=2;
        }else{
            if(s[i]=='J')    cnt1++;
            if(s[i]=='a')    cnt2++;
            if(s[i]=='y')    cnt3++;
        }
    }
    ll ans = min(cnt1,min(cnt2,cnt3));
    
    if(ans==0){
        ans = 1;
        cnt--;
    }
    
    ll m = quick_mod(2ll,cnt);
    ans = (ans * m) %MOD;
    cout << ans << endl;
    
    return 0;
}

总结

还是有点收获:发现自己写基础算法如喝水hhh,写简单题如喝水哈哈哈哈哈哈,,,,,

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辽宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值