CCPC - 문제에 CometOJ 2,019 여름 시즌의 기쁨 솔루션

완전한 이진 트리 K

문제의 의미

알려진 전체 \ (K \) 나무가 (\ N-) \ 노드 사이의 거리, 나무는 멀리 떨어진 두 지점을 찾아 노드는 1이다.

기본 아이디어

트리 요청 깊이 \ (H는 \) 후 전체 \ (K \) , 두 지점 사이의 거리가 트리 인 (\. (1-H) * 2 \) , 층의 나머지 노드 \ (REST \)의 판정을 할 경우 \ (나머지> K ^ {시간 -1} / K \) ANS + 2 인 경우, 또는 (\ 나머지> 0, ANS + 1 \)

#include<bits/stdc++.h> 
#define FOR(i,a,b) for(int i=a;i<b;i++)
#define FOR2(i,a,b) for(int i=a;i<=b;i++)
#define sync ios::sync_with_stdio(false);cin.tie(0) 
#define ll long long
#define MAXN 100010
using namespace std;
int main()
{
    ll count=0,t,n,k;cin>>t;
    while(t--)
    {
        count=0;ll h=0;
        cin>>k>>n;
        if(k==1){
            cout<<n-1<<endl;continue;
        }
        ll sum=0,tmp=1;
        while(1)
        {
            sum+=tmp;
            tmp*=k;
            h++;
            if(tmp+sum>=n)break; 
        }
        ll ans=(h-1)*2;
        n=n-sum;
        if(n>tmp/k)
        {
            ans+=2;
        }
        else if(n>=1)
        {
            ans++;
        }
        
        cout<<ans<<endl;
        
    }
    return  0;
}

미국의 B

문제의 의미

일련의 숫자, 모든 인접 숫자 사이의 차이만큼이 필요 \ (> = k 개의 \)의 변성의 최소 개수

기본 아이디어

스윕 간격 경우 차이는 다음 스캔 (\ <K \) 라고한다 (\ CNT를 ++, 난 \ ++ )
참고의 절대치

#include<bits/stdc++.h> 
#define FOR(i,a,b) for(int i=a;i<b;i++)
#define FOR2(i,a,b) for(int i=a;i<=b;i++)
#define sync ios::sync_with_stdio(false);cin.tie(0) 
#define ll long long
#define MAXN 100010
using namespace std;
int arr[MAXN],brr[MAXN];
int main()
{   
    ll n,k,cnt=0;cin>>n>>k;
     FOR(i,0,n){
        cin>>arr[i];
        if(i!=0)brr[i]=arr[i]-arr[i-1];
     }
     FOR(i,1,n)
     {
        if(abs(brr[i])<k)
         {
            cnt++;
            i++;
         }
     }
     cout<<cnt<<endl;
    return 0;
}

C 토스트

질문의 기본 의미

상대 \는 (N! \)\ (K는 \) 금형 결과

기본 아이디어

만약 요청이 시간 때 곱셈, \ (N-> MOD = \) , 결과는 0이 될 것이고, 루프는 초과하지 않아야 \을 (K \)

#define FOR(i,a,b) for(int i=a;i<b;i++)
#define FOR2(i,a,b) for(int i=a;i<=b;i++)
#define sync ios::sync_with_stdio(false);cin.tie(0) 
#define ll long long
#define MAXN 100010
using namespace std;
int main()
{
    ll n,mod,ans=1;
    cin>>n>>mod;
    if(n>=mod)
    {
        cout<<0<<endl;return 0;
    }
    FOR(i,1,n+1)
    {
        ans=(ans*i);
        if(ans>=mod)
        {
            cout<<0<<endl;return 0;
        }
    }
    n=ans;ans=1;
    FOR(i,1,n+1)
    {
        ans=(ans*i);
        if(ans>=mod)
        {
            cout<<0<<endl;return 0;
        }
    }
    n=ans;ans=1;
    FOR(i,1,n+1)
    {
        ans=(ans*i)%mod;
    }
    cout<<ans<<endl;
    return 0;
}

F는 트리플

문제의 의미

\ (\ N-) 트리플 (\ (A_I, b_i, C_I ) \) 의 경우 한 쌍의 \ ([I, J] (I는 <= J) \) , 만족 \ (* 2 분 (A_I + a_j , b_i + b_j) \ {르 맥스 (A_I + a_j, b_i + b_j)} \) , 합산 모듈 1E9 + (7)의 출력 C_I * C_J 돈 값을 구한다

기본 아이디어

각 트리플의 속성을 추가 \ (2- B_i의 A_I * \)의 추구, 이런 종류의 속성 (\ C_I \) 프리픽스 및 합 수동 양자 요청 \ (최대 (posr)을 그 (2 * A_1 그래서 + 2 * A_ {posr} -b_1
-b_ {posr} <= 0) \) 의 \ ([1, posr] \ ) 의 시작점을 선택하고 종점 것처럼 전방 스캐너로부터 결정된다 \ ([I, J ] \) , 그것이 확실히 보유 \ ([I + 1, K (K <= J.) \) , 사용 후 발견 \ (C_I을 * 합계 [I, J] \) 돈 증가 결정된다. 두 번 정렬합니다.

#include<bits/stdc++.h> 
#define FOR(i,a,b) for(int i=a;i<b;i++)
#define FOR2(i,a,b) for(int i=a;i<=b;i++)
#define sync ios::sync_with_stdio(false);cin.tie(0) 
#define ll long long
#define MAXN 100010
#define MOD (1000000000+7)
#define debug cout<<"debug"<<endl
using namespace std;
typedef struct{
    ll a,b,c,trans;
}NODE;NODE nodes[MAXN];
ll n,sum[MAXN];
bool cmp(NODE n1,NODE n2)
{
    return n1.trans<n2.trans;
}
ll solve()
{
    sort(nodes+1,nodes+n+1,cmp);
    sum[1]=nodes[1].c;
    FOR2(i,2,n)
    {
        sum[i]=nodes[i].c+sum[i-1];
    }
    ll l=1,r=n,posr=0;
    while(l<=r)
    {   
        ll mid=(l+r)/2;
        if(nodes[mid].trans+nodes[1].trans>0){
            r=mid-1;
        } 
        else {
            posr=mid;l=mid+1;
        }
    }
    ll res=0;
    for(l=1,r=posr;l<=r;l++)
    {//确定起点     
        while(l<=r&&nodes[l].trans+nodes[r].trans>0) {
            r--;
            posr--;
        }
        if(r<l) break;
        res=(res+((sum[r]-sum[l-1])%MOD)*nodes[l].c)%MOD; //L~R的和 
    }
    return res; 
}
int main()
{
    cin>>n;
    FOR2(i,1,n)
    {
        cin>>nodes[i].a>>nodes[i].b>>nodes[i].c;
        nodes[i].trans=2*nodes[i].a-nodes[i].b;
    }
    ll ans=solve();
    FOR2(i,1,n)
    {
        nodes[i].trans=2*nodes[i].b-nodes[i].a;
    }
    ans+=solve();
    cout<<ans%MOD<<endl;
    
    return 0;
}

G 학교 농구 대회

문제의 의미

n은 개인, 각각의 다섯 개 가지 속성은, 사람들은 다섯 개 가지 큰 속성을 선출하고자하는 각 속성은 한 사람을 선택할 수 있습니다.

기본 아이디어

멀티탭을 사용하면, 다음 DFS 폭력을 검색, 상위 5 사람들이 각각의 속성을 선택

#include<bits/stdc++.h> 
#define FOR(i,a,b) for(int i=a;i<b;i++)
#define FOR2(i,a,b) for(int i=a;i<=b;i++)
#define sync ios::sync_with_stdio(false);cin.tie(0) 
#define ll long long
#define MAXN 100010
using namespace std;
typedef struct{
    int state[6];
}NODE;NODE nodes[MAXN];
int maxp[6][6];
int vis[MAXN];
ll ans=0;int n;
void dfs(ll level,ll res)
{
    if(level==6)
    {
        ans=max(ans,res); 
        return;
    }
    else {
        for(int i=1;i<=5;i++)
        {
            if(vis[maxp[i][level]]==1)continue;
            vis[maxp[i][level]]=1;//记录选择的队员 
            dfs(level+1,res+nodes[maxp[i][level]].state[level]);
            vis[maxp[i][level]]=0;
        }
    }
}
int main()
{
    cin>>n;
    FOR2(i,1,n)
    {
        for(int j=1;j<=5;j++)
        {
            cin>>nodes[i].state[j];
            for(int k=1;k<=5;k++)
            {//逐个与5个元素比较 
                if(nodes[i].state[j]>nodes[maxp[k][j]].state[j])
                {//插入排序 
                    for(int h=5;h>=k+1;h--)
                        maxp[h][j]=maxp[h-1][j];
                    maxp[k][j]=i;
                    break;
                }   
                
            }
        }
    }
    for(int i=1;i<=5;i++)
    {
        vis[maxp[i][1]]=1;
        dfs(2,nodes[maxp[i][1]].state[1]);
        vis[maxp[i][1]]=0;
    }
    cout<<ans<<endl; 
    return 0;
}

H 할당 된 학생 수

문제의 의미

서로 그들을 다른 만드는 문자열의 수에 추가 요구의 최소 수를 찾아 각 숫자는 감소하지 증가시킬 수있다.

기본 아이디어

정렬하고 각 선택 번호 (이전보다 작은 최소한의 비율이 사전 +1로 상승하는 경우), 즉 최소 개수가 상승 될 수 있고, 획득 \ (최대 (A [-I한다. 1] +. A1,을 [I]) - A [내가] +1이 \) , 같은 관심은 또한 옵션과 곱셈이다.

#include<bits/stdc++.h> 
#define FOR(i,a,b) for(int i=a;i<b;i++)
#define FOR2(i,a,b) for(int i=a;i<=b;i++)
#define sync ios::sync_with_stdio(false);cin.tie(0) 
#define ll long long
#define MAXN 100010
#define MOD (1000000000+7)
using namespace std;
ll n,arr[MAXN],brr[MAXN];
int main()
{
    cin>>n;
    FOR2(i,1,n)
    {
        cin>>arr[i];
    }
    sort(arr+1,arr+1+n);
    ll ans=1;
    FOR2(i,1,n)
    {
        if(i!=1)
        {
            brr[i]=max(arr[i-1]+1,arr[i])+1-arr[i];
            arr[i]=max(arr[i-1]+1,arr[i]);
            ans=(ans*brr[i])%MOD;
        }
            
    }
    cout<<ans%MOD<<endl;
    return 0;
}

나는 초 심장

문제의 의미

N 개의 *의 m 및 K 박스, 랜덤 배치 박스의 매트릭스는, 그것의 출력 (1)에 도달 할 수없는 경우, 오른쪽 길이 저하 왼쪽에서 최단 경로를 찾는;

기본 아이디어

K가 최대를 넘지 않는 (N-1) (m-1), 제 n + m-2 경로

#include<bits/stdc++.h> 
#define FOR(i,a,b) for(int i=a;i<b;i++)
#define FOR2(i,a,b) for(int i=a;i<=b;i++)
#define sync ios::sync_with_stdio(false);cin.tie(0) 
#define ll long long
#define MAXN 100010
using namespace std;
int main()
{
    ll n,m,k;cin>>n>>m>>k;
    if(k>(n-1)*(m-1)) {
        cout<<-1<<endl; 
    }
    else{
        cout<<n+m-2<<endl;
    }
    return 0;
}

추천

출처www.cnblogs.com/tldr/p/11263186.html