1. 程式人生 > 其它 >5.6CF做題日記【Codeforces Round #787 (Div. 3)A~D】(虛擬場補題)

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;
}