386 div2 cf 3

一行上有0-s个点,列车直走到尽头转向,人要从起点x1走到终点x2,列车速度是t1 s/m,人的速度是t2 s/m,列车在p点,d=1代表方向向右,d=-1向左

模拟=_=但是模拟的太痛苦过后看到一个暴力模拟的感觉不错。。

746C.

    cin>>s>>x1>>x2>>t1>>t2>>p>>d;
    int ans = abs(x1-x2)*t2;
    if(t1>=t2) cout<<ans<<endl;
    else {
        bool flag = 0;
        int len = 0;
        while(1){
            if(p==x1) flag = 1;
            if(flag&&p==x2) break;
            if(d==-1){
               p--;
            }else p++;
            if(p==0) d = 1;
            if(p==s) d = -1;
            len++;
        }
        cout<<min(len*t1,ans)<<endl;
    }

746D.
有G和B两种颜色有g个和b个,在长度为n的串里不能出现同一种颜色连续出现大于等于k+1次。构造这个串

模拟。。还是觉得不错所以搬来了。。

int n,k,g,b;
char A = 'G',B = 'B';
void init() {
    cin >>n>>k>>g>>b;
    if(g<b) swap(g,b),swap(A,B);
    if((LL)g>(LL)k*(b+1)){
        puts("NO");
        return ;
    }
    /*
        g/k就是组数
        b要大于等于组数-1

        所以k >= g/(b+1)
        那么连续出现g/(b+1)个最佳

    */
    int i = 0;
    while(i<n){
        int tot = g/(b+1);
        for(int j=0;j<tot;j++){
            i++;
            cout<<A;
        }
        if(b>0)
            i++,cout<<B;
        b--;
        g-=tot;
        //cout<<g<<" "<<b<<" "<<tot<<endl;
    }
}

746E
题意:给你一个长度为n的序列
这个序列可以和1~m中任意一个数字交换
n<=2e5,m<=1e9
问这个序列最少交换几次使整个序列的所有数字不相同且奇数出现的次数等于偶数出现的次数

自己写的时候懵了很久,完全不知道从哪里下手。但是一听题解又很简单。。还是和以前一样的智障。。
题解:因为要所有数字不同,先保留数组中所有只出现一次的数字,并且分成奇偶两份。
分别对奇,偶大于n/2的都删掉
然后我们就可以暴力添加我们需要的数字。

int a[maxn];
queue<int>Q[2],ans;
set<int>S;
map<int, bool>M;

void init() {
    cin >> n >> m;
    int odd = 0, even = 0;
    for(int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
        S.insert(a[i]);
        if(!M[a[i]]) {
            M[a[i]] = true;
            if(a[i]&1) {Q[1].push(a[i]);odd++;}
            else {Q[0].push(a[i]);even++;}
        }
    }
    while(odd>n/2){
        odd--;
        int k = Q[1].front();
        M[k] = 0;
        S.erase(k);
        Q[1].pop();
    }
    while(even>n/2){
        even--;
        int k = Q[0].front();
        M[k] = 0;
        S.erase(k);
        Q[0].pop();
    }
    int res = 0;
    for(int i=1;i<=m;i++){
        if(i&1&&odd<n/2){
            if(!M[i]){
                M[i] = true;
                odd++;
                res++;
                ans.push(i);
            }
        }else if(!(i&1)&&even<n/2){
            if(!M[i]){
                M[i] = true;
                even++;
                res++;
                ans.push(i);
            }
        }
        if(even+odd==n) break;
    }
    if(odd+even!=n) {puts("-1");return ;}
    cout << res << endl;
    for(int i = 0; i < n; i++) {
        if(S.count(a[i])){
            cout<<a[i]<<" ";
            S.erase(a[i]);
        }else {
            cout<<ans.front()<<" ";
            ans.pop();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值