Codeforces Round #492 (Div. 2) 补题日记

71 篇文章 0 订阅

总结本菜鸡还是太菜了 这样下去可不行啊 没人会拿自己只学了两个月当借口 我也不会

必须努力

题意就是零钱满足逻辑换钱最多能换几个

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl

int main(){
    int n,ans = 0;
    scanf("%d",&n);
    if(n/100!=0){ans+=n/100;
    n%=100;
    }
    if(n/20!=0){
    ans+=n/20;
    n%=20;
    }
    if(n/10!=0){
    ans+=n/10;
    n%=10;
    }
    if(n/5!=0){
    ans+=n/5;
    n%=5;
    }
    ans+=n;
    printf("%d\n",ans);

    return 0;
}

B

题意 给你很多队 有人 主人公每次会排下一个队 也就是每个队减去当前时间-1的人数

那么只要队人数小于0 主人公就可以进去 比较笨 写了线段树

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
const int MAX_N  = 100024;
int s[MAX_N<<2],col[MAX_N<<2],que[MAX_N<<2];
void up(int p){
   s[p] = s[p*2]+ s[p*2+1];
}
void build(int p,int l,int r){
    col[p] = 0;
    if(l==r){
        s[p] = que[l];
        return;
    }
    int mid=(l+r)>>1;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    up(p);
}
void down(int p,int l,int r){
    if(col[p]){
        int mid =(l+r)>>1;
        col[p*2] +=col[p];
        col[p*2+1]+=col[p];
        s[p*2]+=col[p]*(mid-l+1);
        s[p*2+1]+=col[p]*(r-mid);
        col[p] = 0;
    }
}
void change(int p,int l,int r,int x,int y,int v){
    if(x<=l&&r<=y){
        col[p]+=v;
        s[p]+=v*(r-l+1);
        return;
    }
    int mid = (l+r)>>1;
    down(p,l,r);
    if(x<=mid) change(p*2,l,mid,x,y,v);
    if(y>mid) change(p*2+1,mid+1,r,x,y,v);
    up(p);
}
int query(int p,int l,int r,int x){
    if(l==r) return s[p];
    int mid = (l+r)>>1;
    down(p,l,r);
    if(x<=mid) return query(p*2,l,mid,x);
    else return query(p*2+1,mid+1,r,x);
}
int main(){
    int n;
    scanf("%d",&n);
    int minn = 1000000005;
    for(int i=1;i<=n;++i){
    scanf("%d",&que[i]);
    minn=min(que[i],minn);
    }
    build(1,1,n);
    if(minn>=n) change(1,1,n,1,n,-(minn-(minn%n)));
    int cnt = 1;
    while(cnt%n==0?query(1,1,n,n)>0:query(1,1,n,cnt%n)>0){
        change(1,1,n,1,n,-1);
        //dbg(cnt);
        cnt++;
    }
    if(cnt>n) printf("%d\n",cnt%n);
    else printf("%d\n",cnt);
    return 0;
}

C

题意就是让你判断正方向走或者反方向走?

贪心找一下影响最大的因子 模拟一下

主要是找绝对值最大的那部证明了当前决策最优化

比如 -2  5  -2 你当前贪心这样不知道怎么走

但是5 -2 -2 你就会走了

#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;

int n;
long long u, v;
double dis(long long a, long long b){
    return sqrt(a * a + b * b);
}

struct vect{
    int id, x, y, val;
};

bool cmp(vect X, vect Y){return abs(X.x) > abs(Y.x);}
vect vec[100000];

bool Psort(vect X, vect Y){return X.id < Y.id;}

main(){
    //freopen("input.txt", "r", stdin);
    cin >> n;
    for (int i = 0; i < n; i++){
        cin >> vec[i].x >> vec[i].y;
        vec[i].id = i;
    }

    sort(vec, vec + n, cmp);

    for (int i = 0; i < n; i++){
        if (dis(u + vec[i].x, v + vec[i].y) < dis(u - vec[i].x, v - vec[i].y)){
            u += vec[i].x;
            v += vec[i].y;
            vec[i].val = 1;
        }
        else{
            u -= vec[i].x;
            v -= vec[i].y;
            vec[i].val = -1;
        }
    }

    sort(vec, vec + n, Psort);

    for (int i = 0; i < n; i++)
        cout << vec[i].val << ' ';
}

D

无非就是重新排个序 比如 3 3 2 2 1 1 变成1 1 2 2 3 3

再用树状数组搞一下逆序数就出来了

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
const int MAX_N = 200;
int C[MAX_N<<2];
int n;
int getsum(int x){
    int res = 0;
    for(;x;x-=x&(-x))
        res+=C[x];
    return res;
}
void change(int x){
    for(;x<=2*n;x+=x&(-x))
        C[x]++;
}
struct node {
    int pos;
    int x;
}arr[MAX_N*2],brr[MAX_N*2];

int main(){
    scanf("%d",&n);
    for(int i=1;i<=2*n;i++){
        scanf("%d",&arr[i].x);
        arr[i].pos = i;
    }
    int cnt = 0;
    for(int i=1;i<=2*n;i++){
        for(int j=i+1;j<=2*n;++j){
            if(arr[i].x==arr[j].x){
                cnt++;
                //dbg(cnt);
                brr[arr[i].pos].x=cnt;
                brr[arr[j].pos].x=cnt;
                continue;
            }
        }
    }
    int ans = 0;
    for(int i=1;i<=2*n;++i){
       //dbg(brr[i].x);
       ans+=i-1-getsum(brr[i].x);
       //dbg(getsum(brr[i].x));
       change(brr[i].x);
    }
    printf("%d\n",ans);
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值