Educational Codeforces Round 129 (Rated for Div. 2)

这一场算新手友好场,至少我这个新手还是比较舒服的.

A. Game with Cards

Problem - A - CodeforcesCodeforces. Programming competitions and contests, programming communityhttps://codeforces.com/contest/1681/problem/A签到,谁手里的最大牌最大谁赢.

#include<bits/stdc++.h>
using namespace std;
const int N =5e5+10,mod=998244353;
void solve()
{
    int maxxa=-1,maxxb=-1;
    int n,m,x;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        maxxa=max(maxxa,x);
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&x);
        maxxb=max(maxxb,x);
    }
    if(maxxa>=maxxb)
    {
        printf("Alice\n");
    }
    else
    {
        printf("Bob\n");
    }
    if(maxxa<=maxxb)
    {
        printf("Bob\n");
    }
    else
    {
        printf("Alice\n");
    }
}
signed main()
{
    int t;
    cin>>t;
    while(t--)
       solve();
    return 0;
}

B. Card Trick

Problem - B - Codeforcesicon-default.png?t=M5H6https://codeforces.com/contest/1681/problem/B题意:有n张牌,每张牌都有自己的值,m次操作,每次把顶部b[i]张牌放到底部去.问最后顶上牌是什么

思路:最近的一场abc的c题

C - Rotationicon-default.png?t=M5H6https://atcoder.jp/contests/abc258/tasks/abc258_c

我写的思路和这个差不多.这个题更加简单,直接在每次交换后记录他们的起始位置即可.最后输出该位置的牌.

#include<bits/stdc++.h>
using namespace std;
const int N =5e5+10,mod=998244353;
int a[200005];
void solve()
{
    int x,n,m,st=0;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
    scanf("%d",&m);
    for(int i=0;i<m;i++)
    {
        scanf("%d",&x);
        st=(st+x)%n;
    }
    printf("%d\n",a[st]);
    return ;
}
signed main()
{
    int t;
    cin>>t;
    while(t--)
       solve();
    return 0;
}

C. Double Sort

Problem - C - Codeforcesicon-default.png?t=M5H6https://codeforces.com/contest/1681/problem/C题意:给你两个数组a,b,每次可以选择i,j,将a[i]与a[j]还有b[i]与b[j]进行交换,问是否可以把它们都交换成非递减顺序的数组,如果可以输出交换的次数和交换的每一步的i和j.

思路:先将两个数组看排序后能不能排序成立.再直接冒泡排序模拟即可.冒泡排序的时间复杂度是小于n方的,不会超出限制.

#include<bits/stdc++.h>
using namespace std;
struct node
{
    int a,b,id;
}edge[105];
struct node1
{
    int x,y;
};
bool cmp(node a,node b)
{
    if(a.a!=b.a)
        return a.a<b.a;
    else
        return a.b<b.b;
}
stack<node1>qu;
void solve()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&edge[i].a);
    }
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&edge[i].b);
        edge[i].id=i;
    }
    sort(edge+1,edge+1+n,cmp);
    for(int i=1;i<n;i++)
    {
        if(edge[i].b>edge[i+1].b)
        {
            printf("-1\n");
            return ;
        }
    }
    for(int i=1;i<=n;i++)//n个数的数列总共扫描n-1次
    {
        for(int j=1;j<=n-i;j++)//每一趟扫描到a[n-i-2]与a[n-i-1]比较为止结束
        {
            if(edge[j].id>edge[j+1].id)//后一位数比前一位数小的话,就交换两个数的位置(升序)
            {
                node t;
                t=edge[j+1];
                edge[j+1]=edge[j];
                edge[j]=t;
                qu.push({j,j+1});
            }
        }
    }
    printf("%d\n",qu.size());
    while(qu.size())
    {
        node1 temp=qu.top();
        qu.pop();
        printf("%d %d\n",temp.x,temp.y);
    }
    return ;
}
signed main()
{
    int t;
    cin>>t;
    while(t--)
       solve();
    return 0;
}

D. Required Length

题意:给你一个n和x,我们每次可以选择x中某一位的数z,然后让x=x*z.问最少几步能够到数位等于n.

思路:直接搜索即可.稍微需要剪枝,map标记已经搜索的状态,然后每次不去数位上的0或者1即可.

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,x,ans=1e18;
map<int,int>ma;
struct node
{
    int x,step;
};
void bfs()
{
    queue<node>qu;
    qu.push({x,0});
    ma[x]=1;
    while(qu.size())
    {
        node bef=qu.front();
        qu.pop();
        int xx=bef.x;
        string s=to_string(xx);
        if(s.size()==n)
        {
            ans=min(ans,bef.step);
            continue;
        }
        for(int i=0;i<s.size();i++)
        {
            int cnt=s[i]-'0';
            if(cnt!=0&&cnt!=1&&ma[cnt*xx]==0)
            {
                qu.push({xx*cnt,bef.step+1});
                ma[xx*cnt]=1;
            }
        }
    }
    return ;
}
void solve()
{
    ma.clear();
    ans=1e18;
    cin>>n>>x;
    set<int>s;
    int t=x;
    while(t)
    {
        s.insert(t%10);
        t/=10;
    }
    set<int>::iterator i;
    int f=0;
    for(i=s.begin();i!=s.end();i++)
    {
        int tt=*i;
        if(tt!=1&&tt!=0)
        {
            f=1;
        }
    }
    if(f==0)
    {
        cout<<"-1\n";
        return ;
    }
    bfs();
    cout<<ans<<"\n";
    return ;    
}
signed main()
{
    solve();
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值