5.6CF做题日记【Codeforces Round #787 (Div. 3)A~D】(虚拟场补题)

 

 

前言

前三个一小时做出来了,但是后面出去没做了,后来d也是自己做的,加油

 

 

题目链接集合

Dashboard - Codeforces Round #787 (Div. 3) - Codeforces

 

A. Food for Animals

 

Problem - A - Codeforces

 

题意

给出 a b c x y,分别指给狗的食物数量,给猫的食物数量,给猫和狗都能吃的食物数量,狗应吃食物数量,猫应吃食物数量; 求猫和狗是否够吃

 

分析

题不难, 但也容易出乱子,这里我用的是看猫和狗需要在c食物里拿多少,然后和c比较

 

代码

#include<iostream>
using namespace std;
int main(){
    int a,b,c,x,y,n=0,t,j=0;
    cin>>t;
    while(t--)
    {
        cin>>a>>b>>c>>x>>y;
        if(a<x) n=x-a;//狗额外需要的
        if(b<y) j=y-b;//猫额外需要的食物
        if((n+j)<=c) cout<<"YES\n";
        else cout<<"NO\n";
        n=0,j=0;
    }
}

 



 

 

 

B. Make It Increasing

 

Problem - B - Codeforces

 

题意

每次可以把一个数除2,下取整,问需要操作多少次才能使序列递增(相邻两数可以相等)

 

分析

从后往前遍历,如果大于后面的数字,就一直除,但是,如果前面尽量小的话,那最后的序列应该是0 1 2 3 4 5 6...... 也就是说满足a[i]>=i-1  (i=1~n-1)

需要注意的是考虑除到0不能再除了,要不然会一直循环(超时警告

 

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;

const int N = 1e5+10;
int a[50];

int main()
{
    int t;
    scanf("%d", &t);
    while(t --)
    {
        int n;
        cin >> n;
        for(int i = 1; i <=n ;i ++)    cin >> a[i];
    
        bool f = 1;
        int times = 0;
        if(a[n]==0 && n!=1)f = 0;
        else
            for(int i= n-1; i >= 1; i --)
            {
                while(a[i]>=a[i+1])    a[i]/=2, times++;
                if(a[i]<i-1)
                {
                    f=0;
                    break;
                }
            }
        if(!f)cout << "-1\n";
        else cout << times<<endl;
            
    }
    return 0;
}

 

 



 

 

 

C. Detective Task

 

Problem - C - Codeforces   类型:模拟

 

题意

画被偷走了,一共有一些人来依次看过画,主人问他们你们来的时候画还有没有,只有拿画人可以撒谎,求有几个人是嫌疑人

每个人只有3种回答:

1:来的时候画还在

0:来的时候画不在

?:记不清了

 

数据范围

t [1,1e4]     s长度总和不大于2e5

 

分析

有几种情况:(代码中有详解)

全是0和?:那就第一个0和前面的问号是嫌疑人

全是1和?:那就最后一个1和后面的问号是嫌疑人

0和1都有出现:那就0和1之间是嫌疑人(包括0和1)

 

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;

const int N = 1e5+10;
int a[50];

int main()
{
    int t;
    scanf("%d", &t);
    while(t --)
    {
        string s;
        cin >> s;
        
        int sum = 0, tem = 0, num1 = 0;
        bool f0 = 0, f1 = 0;//f0是说有没有0出现, f1同理
        for(int i = s.size()-1; i >= 0; i --)
        {
            if(f0 && f1)break;
            if(s[i]=='?') tem ++;
            if(s[i]=='1') f1=1, sum = tem;//把结果传给sum
            else if(s[i]=='0') f0=1, tem=1;//开始计数
            
            if(!f1)
            num1++;
        }
        if(f0 && f1) cout << sum+1<<endl;   //正常0和1之间的个数(包括0 1) 
        else if(f0) cout << tem<<endl;       //0和前面的?的集合
        else if(f1) cout << num1+1 <<endl;  //1和后面?的集合
        else cout <<  s.size()<<endl;//全程都是‘?’
    }
    return 0;
}

 

来了来了, 最有练代码的题来了

 

D. Vertical Paths

 

Problem - D - Codeforces  类型:树,dfs

 

题意

给出一个树,要把数划分成尽量少的路,每一段路不能重复,输出路的数量,以及每条路走过的点

 

分析

大致思路:其实代码是类似于链表的,但是是用vector和queue存的,然后一步步的dfs,但是有些东西还是要注意的(超时警告

1. 不能有重复的路,每次的路清空,不要再留在队里了

2. 超内存的问题,开始开了俩vector套queue,其中一个作为输出,一个是存子节点,后来是把存输出的给直接输出了,但是要提前知道有多少条路

每个父节点,都不用单独开一条路,下面的子节点如果要开路会带着他们,所以路的条数 = n - 父节点个数

 

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;

const int N = 2e5+10;
int n, q[N], idx=0, coun=0;
queue<int> v[N];

void dfs(int root, int q[])
{
    if(v[root].size()==0)//输出
    {
        cout <<idx<<endl;
        for(int i = 0; i < idx; i ++)     cout << q[i]<< ' ';
        cout<<endl;
        idx=0;
        return;
    }
    
    while(v[root].size())
    {
        int t = v[root].front();
        v[root].pop();
        
        q[idx++]=t;
        dfs(t,q);
        idx=0;//走过就清空
    }
}

void init()
{
    for(int i = 0; i<= n;i++)
        while(v[i].size())
        v[i].pop();
    
    idx=0;
    coun =0;
}

int main()
{
    int t;
    scanf("%d", &t);
    while(t --)
    {
        init();
        int root, x;
        cin >> n ;
        for(int i = 1; i <= n; i ++)
        {
            cin >> x;
            if(x!=i)
            {
                v[x].push(i);
                if(v[x].size()==0)//因为当x==i,v[x]里并不会加元素,还是空
                    coun ++;
            } 
            else
                root = i;        
        }
        q[0]=root;
        idx=1;
        
        cout << n-coun <<endl;
        dfs(root,q);
        cout <<'\n';
    }
    return 0;
}

 

posted @ 2022-05-06 20:40  la-la-wanf  阅读(30)  评论(0编辑  收藏  举报