Codeforces Round #492 (Div. 2)

http://codeforces.com/contest/996

A. Hit the Lottery

解法:贪心一下就好了

#include<bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    int ans=0;
    ans+=n/100;
    n%=100;
    ans+=n/20;
    n%=20;
    ans+=n/10;
    n%=10;
    ans+=n/5;
    n%=5;
    ans+=n;
    cout<<ans<<endl;
    //system("pause");
    return 0;
}
B. World Cup

题意:一个人在第一个入口,每个出口有a[i]个人在排队,每一个单位时间这个人往前走一步(如果在最后就走到第一个入口),同时,每个入口排队的人减少一个,如果走到的这个入口没人排队就可以进去,问最后这个人是从哪个入口进去的。
解法:从左往右直接计算在当前入口进去的最小时间。在当前进口进去需要的时间就是i-1+k*n 求出最小的k满足i-1+k*n>=a[i]

#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
int a[maxn];
int main()
{
    ios::sync_with_stdio(false);
    int n,ans=0x7fffffff,pos;
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++){
        int temp=0;
        if(a[i]>=i-1) temp=ceil(double(a[i]-i+1)/double(n));
        if(temp&&i-1+(temp-1)*n>=a[i]) temp--;
        temp=temp*n+i-1;
        if(ans>temp){
            ans=temp;
            pos=i;
        }
    }
    cout<<pos<<endl;
    return 0;
}
C. Tesla

题意:第二,三行是车编号,一四行是车位编号,求出在20000步内把所有车停到对应车位的步骤。
解法:把第二三行看成一个循环,每次先检查能不能直接把车停进去,不行就把所有车顺时针旋转一次。注意必须要有空余的位置才能够把车移动过去

比较恶心的题

#include<bits/stdc++.h>
using namespace std;
#define fst first
#define snd second
const int maxn=55;
int mp[5][maxn],a[maxn*2];
int n,k;
vector<pair<int,pair<int,int>>>v;
void change(int i,int &r,int &c)
{
    if(i<=n) r=2,c=i;
    else r=3,c=2*n-i+1;
}
void go()
{
    if(n==1){
        if(mp[2][1]==0){
            v.push_back({mp[3][1],{2,1}});
            mp[2][1]=mp[3][1];
            mp[3][1]=0;
        }else if(mp[3][1]==0){
            v.push_back({mp[2][1],{3,1}});
            mp[3][1]=mp[2][1];
            mp[2][1]=0;
        }
        return ;
    }
    for(int i=1;i<=n;i++) a[i]=mp[2][i];
    for(int i=1;i<=n;i++) a[2*n-i+1]=mp[3][i];
    int pos=0,r,c;
    for(int i=1;i<=2*n;i++)
        if(a[i]==0){
            pos=i;
            break;
        }
    for(int i=pos-1;i>=1;i--){
        a[i+1]=a[i];
        if(a[i]){
            change(i+1,r,c);
            v.push_back({a[i],{r,c}});
        }
    }
    if(pos!=2*n){
        a[1]=a[2*n];
        if(a[2*n]){
            change(1,r,c);
            v.push_back({a[2*n],{r,c}});
        }
    }else{
        a[1]=0;
    }
    for(int i=2*n;i-1>pos;i--){
        a[i]=a[i-1];
        if(a[i-1]){
            change(i,r,c);
            v.push_back({a[i-1],{r,c}});
        }
    }
    a[pos+1]=0;
    for(int i=1;i<=n;i++) mp[2][i]=a[i];
    for(int i=1;i<=n;i++) mp[3][i]=a[2*n-i+1];
    /*cout<<"****"<<endl;
    for(int i=2;i<=3;i++){
        for(int j=1;j<=n;j++){
            cout<<mp[i][j]<<' ';
        }
        cout<<endl;
    }*/
}
void check()
{
    for(int i=1;i<=n;i++){
        if(mp[2][i]&&mp[1][i]==mp[2][i]){
            v.push_back({mp[2][i],{1,i}});
            k--;
            mp[2][i]=0;
        }
    }
    for(int i=1;i<=n;i++){
        if(mp[3][i]&&mp[4][i]==mp[3][i]){
            v.push_back({mp[3][i],{4,i}});
            k--;
            mp[3][i]=0;
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>k;
    for(int i=1;i<=4;i++){
        for(int j=1;j<=n;j++)
            cin>>mp[i][j];
    }
    int cnt=0;
    while(k&&cnt<=20000){
        check();
        if(k==0) break;
        go();
        cnt++;
    }
    if(cnt>20000){
        cout<<-1<<endl;
        return 0;
    }
    cout<<int(v.size())<<endl;
    for(auto it:v)
        cout<<it.fst<<' '<<it.snd.fst<<' '<<it.snd.snd<<endl;
    return 0;
}
D. Suit and Tie

题意:给定一个序列(每个数都会只出现两次),每次操作可以交换两个相邻的数,求出把序列变成相等的数相邻的最小操作次数
解法:贪心一下,从左往右,依次把与当前相等的数移过来就好

#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
int a[maxn];
int main()
{
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    for(int i=1;i<=2*n;i++) cin>>a[i];
    int ans=0;
    for(int i=1;i<=2*n;i+=2){
        for(int j=i+1;j<=2*n;j++){
            if(a[j]==a[i]){
                ans+=j-i-1;
                for(int k=j;k>i;k--) swap(a[k],a[k-1]);
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}
E. Leaving the Bar

题意:有n个向量,可以对向量进行反向,求出把所有向量加起来后的模长<1.5e6 的方案(-1表示对向量进行反向)
解法:先遍历所有的向量,如果加上该向量后总模长比减去该向量模长短,则这个向量不用反向,否则就反向;然后再对答案进行一次修正

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define x first
#define y second
const int maxn = 1e5 + 5;
pair<pair<int, int>, int>p[maxn];
int n;
int c[maxn];
LL maxx = 1.5 * 1e6;
int main()
{
    ios::sync_with_stdio(false);
    cin >> n;
    for(int i = 1; i <= n; i++) {
        cin >> p[i].x.x >> p[i].x.y;
        p[i].y = i;
    }
    int sumx = 0, sumy = 0;
    for(int i = 1; i <= n; i++) {
        LL t1 = 1LL * (sumx + p[i].x.x) * (sumx + p[i].x.x) + 1LL * (sumy + p[i].x.y) * (sumy + p[i].x.y);
        LL t2 = 1LL * (sumx - p[i].x.x) * (sumx - p[i].x.x) + 1LL * (sumy - p[i].x.y) * (sumy - p[i].x.y);
        if(t1 <= t2) {
            c[p[i].y] = 1;
            sumx += p[i].x.x;
            sumy += p[i].x.y;
        } else {
            c[p[i].y] = -1;
            sumx -= p[i].x.x;
            sumy -= p[i].x.y;
        }
    }
    for(int i = 1; i <= n; i++) {
        LL temp = 1LL * sumx * sumx + 1LL * sumy * sumy;
        if(temp <= maxx) {
            break;
        }
        LL t1, t2;
        if(c[i] == 1) {
            t1 = sumx - 2 * p[i].x.x;
            t2 = sumy - 2 * p[i].x.y;
            if(t1 * t1 + t2 * t2 < temp) {
                sumx = t1;
                sumy = t2;
                c[i] = -1;
            }
        } else {
            t1 = sumx + 2 * p[i].x.x;
            t2 = sumy + 2 * p[i].x.y;
            if(t1 * t1 + t2 * t2 < temp) {
                sumx = t1;
                sumy = t2;
                c[i] = 1;
            }
        }
    }
    for(int i = 1; i <= n; i++) {
        cout << c[i] << ' ';
    }
    return 0;
}
F. Game

题意都没有读懂

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值