Codeforces Round #492 (Div. 2) [Thanks, uDebug!] ABCDE (模拟 + 贪心 + 思维 + 随机化)

A:有5,20,,,,的金币,然后怎么怎么样,略

B:有n个数,每次走一步,每个数都会减少1,当减少到0的时候就不会改变了,问你最少多少步可以走到是0的数上

ll a[maxn];
int main() {
    ios::sync_with_stdio(false);
    while(cin >> n){
        for(int i = 1;i <= n;i++){
            cin >> a[i];
        }
        ll ans = 0;
        while(1){
            for(int i = 1;i <= n;i++){
                if(a[i] < i){
                    cout << i << endl;
                    return 0;
                }
            }
            int Min = 1e9;
            for(int i = 1;i <= n;i++)  Min = min(Min,a[i] / n);
            if(Min == 0){
                while(1){
                    for(int i = 1;i <= n;i++){
                            a[i] -= i;
                            if(a[i] < 0){
                                cout << i << endl;
                                return 0;
                            }
                            a[i] -= (n - i);
                    }
                }
            }
            for(int i = 1;i <= n;i++){
                a[i] = max(0,a[i] - Min * n);
            }
        }

    }
}

代码写的有点丑了,反正就是模拟加模拟,先除一边,然后挨个减,当除数为0的时候,去减一下就可以了(因为跑不过两轮就会结束)

C:(模拟),有n * 2 个停车位,以及一些车车,每个车都有一个编号,它必须·停在编号相同的停车场里,在不超过20000

可以把第四行和第三行折到第一行和第二行上,这样在处理的时候 就方便多了,然后对于每次只要移动第二行的上的车车就可以了,具体模拟的时候下标怎么变动 , 大家自己模拟一下就知道了。

代码:


ll n,k,m;
int a[5][maxn];
struct node{
    int id,x,y;
};
vector<node>ans;
P getxy(int id,int x) {
     P p;
     if(id == 2){
        if(x > n){
            x -= n;
             p.fi = 3,p.se = (n - x + 1);
        }else p.fi = id,p.se = x;
     }else{
        if(x > n){
            x -= n;  p.fi = 4,p.se = (n - x + 1);
        }else p.fi = id,p.se = x;
     }
     return p;
}
void getans(P p,int k)
{
    ans.push_back(node{k,p.fi,p.se});
     return ;
}
bool vis[maxn];
bool check(int i){
    if(a[1][i] == a[2][i] && a[2][i] != 0&&!vis[i]){ 
        int x = 1, y = i;
        vis[i] = 1;
        P p = getxy(1,i);
        getans(p,a[2][i]);
        a[2][i] = 0;
        k--;
    } 
}
void movee(){
    int id = 1;
    for(int i = 1;i <= 2 * n;i++){
        if(a[2][i] == 0){
            id = i;break;
        }
    } 
    for(int i = id;i >= 1;i--){ 
        if(a[2][i - 1]){
            if(i == 1){
                P p = getxy(2,2 * n);
                getans(p,a[2][i - 1]);
                swap(a[2][2 * n],a[2][i ]);
            }else{
                P p = getxy(2,i);
                getans(p,a[2][i - 1]);
                swap(a[2][i- 1],a[2][i ]);
            }
        }  
    }
    for(int i = n * 2;i >= id + 1;i--){
        if(a[2][i]){
            if(i == 2 * n){
                P p = getxy(2,1);
                getans(p,a[2][i]);
                swap(a[2][2 * n],a[2][1]);
            }else {
                P p = getxy(2,i + 1);
                getans(p,a[2][i]);
                swap(a[2][i +1],a[2][i]);
            }
        }
    }
    return ;
}
int main() {
    n = read();k = read();
    for(int j = 1;j <= 4;j++)  for(int i = 1;i <= n;i++) a[j][i] = read();
    ll x = k;
    for(int j = 1;j <= n;j++) a[1][n + j] = a[4][n + 1 - j];
    for(int j = 1;j <= n;j++) a[2][n + j] = a[3][n + 1 - j];
    for(int i = 1;i <= 2 * n;i++) check(i);
    int flag = 0;
    for(int i = 1;i <= n * 2;i++) if(a[2][i] == 0) flag = 1;
    if(!flag) return cout << -1 <<endl,0;
    while(k){
        for(int i = 1;i <= n * 2;i++)
            check(i) ;
        movee();
    }
    cout << ans.size() << endl;
    for(auto d:ans) cout << d.id << " " <<d.x << " " << d.y << endl;
    return 0;
}
//

D:让你用最小的移动次数,把n * 2 个数,相同的数变成相邻的。

前面的数不动,直接模拟就可以了。

ll n,k;
ll a[maxn];
vector<int>v[maxn];
int main() {
    ios::sync_with_stdio(false);
    while(cin >> n){
        for(int i = 1;i <= n * 2;i++) cin >> a[i],v[a[i]].push_back(i);
        int ans = 0;
        int l = 1,r = 1; 
            for(int i = 1;i <= n * 2;i += 2){
                if(a[i] != a[i + 1]){
                        int id = 0;
                    for(int j = i + 1; j <= n * 2;j++){ 
                        if(a[i] == a[j]){
                            id = j;
                            break;
                        }
                    } 
                    for(int j = id;j > i + 1;j--){
                        ans ++;swap(a[j],a[j - 1]); 
                    } 
                } 
        }
        cout << ans << endl;
    }
    return 0;
}

E:有n个向量,你可以取正或者负,最后走完这些向量,要求距离原点不超过1.5e6

随机化 + 枚举,找出来一种符合的方式(具体原理我也搞不懂,自己随机贪心一直T39)

ll n,k,m;
ll a[maxn];
struct node{
    ll a,b,id,ans;
}p[maxn];
bool cmp(node a,node b){
    return abs(a.a - a.b) < abs(b.a - b.b);
}
bool cmp1(node a,node b){
    return a.id < b.id ;
}
int main() {
    ios::sync_with_stdio(false);
    while(cin >> n){
        for(int i = 1;i <= n;i++) cin >> p[i].a >>p[i].b,p[i].id = i;
        while(1){
            random_shuffle(p + 1,p + 1 + n);
    //        sort(p + 1,p + 1 + n,cmp);
            ll x = 0,y = 0; ll  dis = 0;
            for(int i = n;i >= 1;i--){
               dis = (x + p[i].a) * (x + p[i].a)  + (y + p[i].b) * (y + p[i].b);
                if(dis <= (x - p[i].a) * (x - p[i].a)  + (y - p[i].b) * (y - p[i].b) ){
                    x += p[i].a;
                    y += p[i].b;
                    dis = x * x + y * y;
                    p[i].ans = 1;
                }else{
                    x -= p[i].a;
                    y -= p[i].b;
                    dis = x * x + y * y;
                    p[i].ans = -1;
                }
            }
//            cout << dis << endl;
            if(sqrt(dis) <= 1.5e6){
                break;
            }
        }
        sort(p + 1,p + 1 + n,cmp1);
        for(int i = 1;i <= n;i++){
            cout << p[i].ans << " ";
        }
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值