YNU.cpc

横浜国立大学競技プログラミング部 ( YNU.cpc )

活動日記 day 27

活動内容 :
コンテスト ( 個人戦 )
コンテスト : AtCoder Virtual Contest



コメント :
木の直径の求め方を覚えましょう。

A : 高橋くんと年齢
解法 1
実際にソートして真ん中を出力

#include<bits/stdc++.h>
 
#define REP(i,s,n) for(int i=s;i<n;++i)
#define rep(i,n) REP(i,0,n)
 
using namespace std;
 
int main() {
  int arr[3];
  rep(i,3) cin >> arr[i];
  sort(arr,arr+3);
  cout << arr[1] << endl;
  return 0;
}

解法 2
総和 - 最大値 - 最小値

#include<bits/stdc++.h>
 
using namespace std;
 
int main() {
  int a,b,c;
  cin >> a >> b >> c;
  cout << ( a + b + c ) - max(a,max(b,c)) - min(a,min(b,c)) << endl;
  return 0;
}

B: 高橋くんと文字列圧縮
その通りにシミュレーションしましょう。

#include<bits/stdc++.h>
 
#define REP(i,s,n) for(int i=s;i<n;++i)
#define rep(i,n) REP(i,0,n)
 
using namespace std;
 
int main() {
  string s;
  cin >> s;
  rep(i,(int)s.size()) {
    cout << s[i];
    int cnt = 1;
    int sp = i;
    while( i+1 < (int)s.size() && s[sp] == s[i+1] ) {
      ++cnt, ++i;
    }
    cout << cnt;
  } puts("");
  return 0;
}

C: 高橋くんと魔法の箱
入力で与えられた各値について、2で割る限り割り続けます。
その後に残った値の種類の数が答えです。

#include<bits/stdc++.h>
 
#define REP(i,s,n) for(int i=s;i<n;++i)
#define rep(i,n) REP(i,0,n)
 
using namespace std;
 
typedef long long ll;
 
int n,a[100010];
 
int main() {
  cin >> n;
  rep(i,n) {
    cin >> a[i];
    while( a[i] % 2 == 0 ) a[i] /= 2;
  }
  set<int> S;
  rep(i,n) S.insert(a[i]);
  cout << (int)S.size() << endl;
  return 0;
}

D: 高橋くんと木の直径
木の直径の求め方をそのまま実行します。
木の直径の求め方は以下の通りです。
1. どこでも良いので1つノードを選んでそこから最も遠いノードxを求めます。
2. 先ほど求めたノードxから最も遠いノードyを求めます。
xとyの距離が木の直径です。

詳細はあり本に蟻ます。

#include<bits/stdc++.h>
 
#define REP(i,s,n) for(int i=s;i<n;++i)
#define rep(i,n) REP(i,0,n)
 
using namespace std;
 
typedef long long ll;
 
int main() {
  int n,v;
  cin >> n;
  vector<int> dist1;
  dist1.push_back(0);
  REP(i,1,n) {
    cout << "? 1 " << i+1 << endl;
    cin >> v;
    dist1.push_back(v);
  }
  int next_sp = 0;
  REP(i,1,n) {
    if( dist1[next_sp] < dist1[i] ) next_sp = i;
  }
  int maxi = 0;
  rep(i,n) {
    if( i != next_sp ) {
      cout << "? " << next_sp+1 << " " << i+1 << endl;
      cin >> v;
      maxi = max(maxi,v);
    }
  }
  cout << "! " << maxi << endl;
  return 0;
}