AtCoder Beginner Contest #026 C問題 - 高橋君の給料

Source

AtCoder Beginner Contest #026
問題文

問題概要

$N$ 人の社員がいて,番号が $1$ から $N$ までで付けられている.
また,$1$ 番の社員以外は直属の上司がいて,上司の番号は自分の番号よりも小さい.
部下のいない社員の給料は $1$ で,部下のいる社員の給料は,その部下の給料のうち,最小値と最大値を足したものに $1$ を加えたものである.
それぞれの社員について,直属の上司の情報が与えられるので,$1$ 番の社員の給料を求める問題.

解法

データを,各社員からその部下を列挙できる形にしておいて,番号の大きい社員から順番に給料を求めていけば良い.
時間計算量は $O(N)$.

C++によるスパゲッティなソースコード

#include<bits/stdc++.h>
using namespace std;

#define REP(i,a,b) for(i=a;i<b;i++)
#define rep(i,n) REP(i,0,n)

#define mygc(c) (c)=getchar_unlocked()
#define mypc(c) putchar_unlocked(c)

void reader(int *x){int k,m=0;*x=0;for(;;){mygc(k);if(k=='-'){m=1;break;}if('0'<=k&&k<='9'){*x=k-'0';break;}}for(;;){mygc(k);if(k<'0'||k>'9')break;*x=(*x)*10+k-'0';}if(m)(*x)=-(*x);}
void writer(int x, char c){int s=0,m=0;char f[10];if(x<0)m=1,x=-x;while(x)f[s++]=x%10,x/=10;if(!s)f[s++]=0;if(m)mypc('-');while(s--)mypc(f[s]+'0');mypc(c);}
template<class T> void writerLn(T x){writer(x,'\n');}

int N;
int dp[20];
int edge[20][20], es[20];

int main(){
  int i, j, k;
  int mn, mx;

  reader(&N);
  rep(i,N) es[i] = 0;
  REP(i,1,N){
    reader(&j);
    j--;
    edge[j][es[j]++] = i;
  }

  for(i=N-1;i>=0;i--){
    if(es[i]==0){ dp[i] = 1; continue; }
    mn = mx = dp[edge[i][0]];
    REP(j,1,es[i]){
      mn = min(mn, dp[edge[i][j]]);
      mx = max(mx, dp[edge[i][j]]);
    }
    dp[i] = mn+mx+1;
  }
  writerLn(dp[0]);

  return 0;
}

Current time: 2017年09月21日05時03分04秒
Last modified: 2015年07月24日06時44分25秒 (by laycrs)
Tags: Competitive_Programming AtCoder AtCoder_Beginner_Contest ABC026 ABC_C
トップページに戻る

Logged in as: unknown user (not login)

ログイン: