2020牛客多校第九场

  • A Groundhog and 2-Power Representation
    题意:
    给你一个用2的多少多少幂次加起来的字符串,其中1用2(1)表示,2就用2表示,问你这个字符串表示的数是多少?
    解法:
    1.python牛逼,eval牛逼,直接把(替换成**(然后eval一下就是答案
    2.递归写法,待补(用java)
s=input()
s=s.replace('(', '**(')
print(eval(s))
  • I The Crime-solving Plan of Groundhog
    题意:
    给你n个数,范围[0,9],保证这n个数里至少有两个数的值非0,现在问你用这n个数拼成两个正整数,然后让这两个正整数相乘,能得到的最小乘积是多少。
    思路:
    比赛里猜了一波结论,一定是(n-1)个数和1个数相乘得到的数最小,那1个数肯定是除了0最小的那个数,剩下来n-1个数来构造最小的数,首先把最小数放在最前面,然后在第一个数之后全都放0,然后把剩下的数从小到大放在后面。
    证明方法先可以由1位*3位 > 2位*2位推广。
#include <bits/stdc++.h>
using namespace std;
const int maxn=(int)1e5+100;
int tc,n,a[maxn];
int main() {
    ios::sync_with_stdio(false);cin.tie(0);cout.precision(10);cout << fixed;
#ifdef LOCAL_DEFINE
    freopen("input.txt", "r", stdin);
#endif
    cin>>tc;
    while(tc--){
        cin>>n;
        int cnt0=0;
        vector<int> res;
        for(int i=1; i<=n; ++i){
            cin>>a[i];
            if(a[i]==0) ++cnt0;
            else res.emplace_back(a[i]);
        }
        sort(res.begin(), res.end());
        int b=res[0];
        string a="";
        a+=char((int)'0'+res[1]);
        for(int i=0; i<cnt0; ++i) a+='0';
        for(int i=2; i<int(res.size()); ++i) a+=char(int('0')+res[i]);
        string ans="";
        int add=0;
        for(int i=int(a.size())-1; i>=0; --i){
            int num=int(a[i]-'0');
            int mul=num*b;
            mul+=add;
            add=mul/10;
            ans+=char(int('0')+mul%10);
        }
        if(add>0) ans+=char(int('0')+add);
        reverse(ans.begin(), ans.end());
        cout<<ans<<'\n';
    }
#ifdef LOCAL_DEFINE
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
    return 0;
}

  • F Groundhog Looking Dowdy
    题意:
    输入n和m,表示n天中要选m天穿衣服,下面输入n行,每行一个数为num,接下来num个数分别表示第i天穿的衣服的魅力值。现在问你选m天里每天穿一件衣服,最小的(max魅力值-min魅力值)是多少。
    解法:
    尺取法:求满足条件的最小区间
    把所有衣服放在一个struct里面,然后根据魅力值sort,就转化成了可以用尺取法解决的问题。
#include <bits/stdc++.h>
using namespace std;
const int maxn=2*(int)1e6+100;
int n,m,cnt[maxn];
struct node{
    int x,id;
}nd[maxn];
bool cmp(node a, node b){
    return a.x<b.x;
}
int main() {
    ios::sync_with_stdio(false);cin.tie(0);cout.precision(10);cout << fixed;
#ifdef LOCAL_DEFINE
    freopen("input.txt", "r", stdin);
#endif
    cin>>n>>m;
    int tot=0;
    for(int i=1; i<=n; ++i){
        int num,temp;
        cin>>num;
        for(int j=0; j<num; ++j){
            cin>>temp;
            nd[++tot].x=temp;
            nd[tot].id=i;
        }
    }
    sort(nd+1, nd+1+tot, cmp);
    int ans=INT_MAX;
    int l=1,r=1,sum=0;
    memset(cnt,0,sizeof(cnt));
    for(;;){
        while(r<=tot && sum<m){  //看了半天,应该是tot而不是n,脑残了
            if(cnt[nd[r].id]==0){
                ++sum;
            }
            ++cnt[nd[r++].id];
        }
        if(sum<m) break;
        ans=min(ans, nd[r-1].x-nd[l].x);
        --cnt[nd[l].id];
        if(cnt[nd[l++].id]==0){
            --sum;
        }
    }
    cout<<ans<<'\n';
#ifdef LOCAL_DEFINE
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
    return 0;
}

  • K The Flee Plan of Groundhog
    题意:
    有一个n个点n-1条边的无向无环图,a同学在点1,b同学在点n,一开始t时间内a同学疯狂往b走,每秒可以走一条边。然后t时候已过a同学就会发现b同学发烧了,疑似感染了COVID19啊,他从想要疯狂靠近b同学变成了想要疯狂远离b同学,但b同学并不认为他感染了COVID19,他认为只是普通感冒,而且想要靠近a同学证明给他看,并且b同学的体育比较好,所以b同学每秒可以走两条边,现在的情况是t时间后a同学要尽可能的远离b同学,b同学要尽可能靠近a同学,问最多多少时间后他们俩一定会碰头。
    1≤n≤100000 ,1 ≤t≤ n−1, 1≤x,y≤n.
    思路:
    首先如果t时间内a会碰到b,答案不是1,而是0,问了出题人,他说t时间一过,b同学已经抓住a同学了,所以是0。我原本特判的是1,改了0就过了,2333。
    首先dfsO(n)找从1到n的path,找到了path之后就到了特判环节,如果path.size()-1(边数)小于等于t时,答案就是1。
    接下来就是t时间内a同学碰不到b同学的情况,O(n) dfs一下点a(不能是到b的那条边)得到最远的点是c。然后设s1为c到b的距离,s2为c到a的距离,s1为c到a的距离,现在有两种情况。
  1. s1-s2 <= s2
    a还没跑到最远点就没抓了,因为每秒一过,b和a的距离就缩短了1,所以答案是s2-s1。
  2. s1-s2 > s2
    a跑到最远点没法了啊,哪也去不了,那就呆着吧(题目允许stay put),然后所需时间为(s1+1)/2。(需要向上取整,比如5米需要3秒)
#include <bits/stdc++.h>
using namespace std;
const int maxn=(int)1e5+100;
int n,t,d[maxn];
bool flag;
vector<int> G[maxn];
vector<int> path;
void findPath(int now, int pref){
    if(flag) return;
    path.emplace_back(now);
    if(now==n){
        flag=true;
        return;
    }
    for(int to:G[now]){
        if(to==pref) continue;
        findPath(to, now);
    }
    if (!flag) path.pop_back();
}
void dfs(int now, int pref, int cnt){
    d[now]=cnt;
    for(int to:G[now]){
        if(to==pref) continue;
        if(d[to]==-1){
            dfs(to, now, cnt+1);
        }
    }
}
int main() {
    ios::sync_with_stdio(false);cin.tie(0);cout.precision(10);cout << fixed;
#ifdef LOCAL_DEFINE
    freopen("input.txt", "r", stdin);
#endif
    path.clear();
    flag=false;
    cin>>n>>t;
    for(int i=0; i<n-1; ++i){
        int u,v;
        cin>>u>>v;
        G[u].emplace_back(v);
        G[v].emplace_back(u);
    }
    findPath(1, 0);
    if(int(path.size())-1<=t) cout<<0<<'\n';
    else{
        for(int i=0; i<=n; ++i) d[i]=-1;
        dfs(path[t], path[t+1], 0);
        int maxx=-1, u;
        for(int i=1; i<=n; ++i){
            if(d[i]>maxx){
                maxx=d[i];
                u=i;
            }
        }
        for(int i=0; i<=n; ++i) d[i]=-1;
        dfs(u, 0, 0);
        int s1=d[n], s2=d[path[t]];
        if(s1-s2<=s2) cout<<s1-s2<<'\n';
        else cout<<(s1+1)/2<<'\n';
    }
#ifdef LOCAL_DEFINE
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
    return 0;
}

  • E Groundhog Chasing Death
    题意:
    求i从[a,b],j从[c,d]的gcd(i,j)累乘
    思路:
    待补。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值