Educational Codeforces Round 118 (Rated for Div. 2) ABCDE

Educational Codeforces Round 118 (Rated for Div. 2) ABCDE

A. Long Comparison
题意
t组数据,每组数据给x1、p1、x2、p2代表两个数A,B。
A是x1后面加p1个0,B是x2后面加p2个0。比较A,B的大小。
思路
先比较长度,在长度相同的时候再一位位的比较大小。

#include<bits/stdc++.h>
using namespace std;
int p1,p2,len1,len2;
string x1,x2;

void solve(){
    cin>>x1>>p1>>x2>>p2;
    len1=x1.length(); len2=x2.length();
    if(len1+p1>len2+p2){puts(">");return;}
    if(len1+p1<len2+p2){puts("<");return;}
    int len=len1+p1,mi=min(len1,len2);
    for(int i=0;i<mi;i++){
        if(x1[i]>x2[i]){puts(">");return;}
        if(x1[i]<x2[i]){puts("<");return;}
    }
    if(len1>len2){
        for(int i=mi;i<len1;i++){
            if(x1[i]!='0'){puts(">");return;}
        }
        puts("=");
    }
    else if(len1<len2){
        for(int i=mi;i<len2;i++){
            if(x2[i]!='0'){puts("<");return;}
        }
        puts("=");
    }
    else puts("=");
}

int main(){
    int t;scanf("%d",&t);
    while(t--) solve();
}

B. Absent Remainder
题意
t组数据,每组数据由一个长度为n的a数列组成。
要求输出 ⌊ n 2 ⌋ ⌊n2⌋ n2 x % y x\%y x%y不在a数列的元素对。
思路
直接贪心就行了,每次取y为a数列的最小值,再依次取 ⌊ n 2 ⌋ ⌊n2⌋ n2个元素做x

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,a[N];

void solve(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    sort(a+1,a+n+1);
    int ned=n/2;
    int idx=2;
    while(ned){
        printf("%d %d\n",a[idx],a[1]);
        ned--;idx++;
    }
}

int main(){
    int t;scanf("%d",&t);
    while(t--) solve();
}

C. Poisoned Dagger
题意
t组数据,n个时间点可以攻击,龙的血量是h,问一次攻击持续多久可以打败龙。每次攻击在持续的时候要是到了下一个攻击时间点,那么攻击时间重新累计。
思路
cf里面很常见的一种二分,我们直接二分答案,找到最小符合条件的攻击持续时间就行了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=105;
ll n,h,a[N];

bool cek(ll mid){
    ll sum=0;
    for(ll i=1;i<=n;i++){
        if(i!=n) sum+=min(mid,a[i+1]-a[i]);
        else sum+=mid;
    }
    return sum>=h;
}

void solve(){
    scanf("%lld%lld",&n,&h);
    for(ll i=1;i<=n;i++) scanf("%lld",&a[i]);
    ll l=1,r=h,ans=h;
    while(l<=r){
        ll mid=(l+r)>>1;
        if(cek(mid)) ans=mid,r=mid-1;
        else l=mid+1;
    }
    printf("%lld\n",ans);
}

int main(){
    int t;scanf("%d",&t);
    while(t--)solve();
    return 0;
}

D. MEX Sequences
题意
一共有多少 MEX-CORRECT的序列
如果一个序列被认为是MEX-CORRECT 的 那么 ∣ x i − M E X ( x 1 … x i ) ∣ < = 1 |xi-MEX(x1…xi)|<=1 xiMEX(x1xi)<=1
(如果 i=1 就满足 ∣ x 1 − M E X ( x 1 ) ∣ < = 1 |x1-MEX(x1)|<=1 x1MEX(x1)<=1,如果i=2 要满足 ∣ x 1 − M E X ( x 1 ) ∣ < = 1 和 ∣ x 2 − M E X ( x 1 , x 2 ) ∣ < = 1 ) |x1-MEX(x1)|<=1和 |x2-MEX(x1,x2)|<=1) x1MEX(x1)<=1x2MEX(x1,x2)<=1)

思路
计数DP,根据MEX的性质,我们知道MEX是序列中没有出现的最小非负数,那么要满足 ∣ x i − M E X ( x 1 … x i ) ∣ < = 1 |xi-MEX(x1…xi)|<=1 xiMEX(x1xi)<=1,(根据样例1也可以知道),我们也知道满足条件的只有两种情况。
①:0 0 1 1 2 2 这样从0开始一直前后变化+0、+1
②:0 0 1 1 3 3 1 1 中间只缺了一个数字

然后写DP就行了,注意开longlong,和最后答案mod998244353

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=5e5+5;
const ll mod=998244353;
ll n,dp[N][2];//0为情况①,1为情况②

void solve(){
    scanf("%lld",&n);
    dp[0][0]=1;
    for(ll i=1;i<=n;i++){
        ll x;scanf("%lld",&x); x++;
        dp[x][0]=(dp[x][0]+dp[x][0])%mod;
        dp[x][0]=(dp[x][0]+dp[x-1][0])%mod;
        if(x>=2) dp[x][1]=(dp[x][1]*2%mod+dp[x-2][0])%mod;
        if(x<=n-2) dp[x+2][1]=(dp[x+2][1]+dp[x+2][1])%mod;
    }
    ll sum=0;
    for(ll i=1;i<=n+2;i++){
        sum+=(dp[i][0]+dp[i][1])%mod;
        dp[i][0]=dp[i][1]=0;
    }   
    printf("%d\n",sum%mod);
}

int main(){
    int t;scanf("%d",&t);
    while(t--) solve();
}

E. Crazy Robot
题意
有一个不听话的机器人,不会按照执行移动,即你说往左,它绝不往左;说往右,它绝不往右。同时在地图上有墙(‘#’),有目的地(‘L’),有空地(‘.’),要求我们将一定可以到达的空地变成(‘+’),然后输出新地图。

思路
直接bfs,听说复杂度可以过???然后对于加入队列的点,需要满足在通过上一个点bfs判断的时候,周围只有一个方向移动就行了。就for方向的时候,多for一次方向,记录一下可以移动的方向就好了。(具体看代码)

#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<int,int>PII;
const int N=1e6+5;
int n,m;
map<PII,bool>vis;
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
char s[N];
int sx,sy;
vector<char>mp[N];

void bfs(int xx,int yy){
    queue<PII>q;
    q.push({xx,yy});
    vis[{xx,yy}]=true;
    while(!q.empty()){
        auto u=q.front(); q.pop();
        for(int i=0;i<4;i++){
            int nx=u.x+dx[i],ny=u.y+dy[i];
            if(nx>=0&&nx<n&&ny>=0&&ny<m&&!vis[{nx,ny}]&&mp[nx][ny]=='.'){
                int cnt=0;
                for(int j=0;j<4;j++){
                    int bx=nx+dx[j];
                    int by=ny+dy[j];
                    if(bx==u.x&&by==u.y) continue;
                    if(bx>=0&&bx<n&&by>=0&&by<m&&mp[bx][by]=='.') cnt++;
                }
                if(cnt<=1){
                    mp[nx][ny]='+';
                    vis[{nx,ny}]=true;
                    q.push({nx,ny});
                }
            }
        }
    }
}

void solve(){
    vis.clear();
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        mp[i].clear();
        for(int j=0;j<m;j++){
            char op; scanf(" %c",&op);
            if(op=='L'){sx=i,sy=j;}
            mp[i].push_back(op);
        }
    }
    bfs(sx,sy);
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            printf("%c",mp[i][j]);
        }
        printf("\n");
    }
}

int main(){
    int t;scanf("%d",&t);
    while(t--) solve();
}

F. Tree Coloring
思路
我也不会

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值