ichirin2501's diary

いっちりーん。

第7回JOI予選

0521(aoj) : おつり
0522(aoj) : JOIとIOI
0523(aoj) : カードゲーム
0524(aoj) : 星座探し
0525(aoj) : おせんべい
0526(aoj) : 船旅

0521

やるだけ、見るも無残なくそこーど。

#include <iostream>
int main()
{
  int n;
  while(std::cin>>n,n){
    n = 1000-n;
    int ans = 0;
    while(n>=500){
      n-=500; ans++;
    }
    while(n>=100){
      n-=100; ans++;
    }
    while(n>=50){
      n-=50; ans++;
    }
    while(n>=10){
      n-=10; ans++;
    }
    while(n>=5){
      n-=5; ans++;
    }
    ans += n;
    printf("%d\n",ans);
  }
  return 0;
}



0522

やるだけ

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string str;
  while(cin>>str){
    int pos = 0;
    int joi,ioi;
    joi = ioi = 0;
    while( (pos=str.find("JOI",pos)+1) )joi++;
    pos = 0;
    while( (pos=str.find("IOI",pos)+1) )ioi++;
    
    printf("%d\n%d\n",joi,ioi);
  }
  return 0;
}



0523

やるだけ

#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
  int n;
  
  while(cin>>n,n){
    vector<int> taro,hana;
    int num[201];
    memset(num,0,sizeof(num));
    
    for(int i=0; i<n; i++){
      int a; cin>>a;
      num[a]=1;
    }
    
    for(int i=1; i<=2*n; i++){
      if( num[i] )taro.push_back(i);
      else       hana.push_back(i);
    }
    
    int turn=1;
    int ba = 0;
    for(; taro.size() && hana.size();){
      if( turn ){
        vector<int>::iterator it = lower_bound(taro.begin(),taro.end(),ba);
        if( it==taro.end() )ba=0;
        else{
          ba = *it;
          taro.erase( it );
        }
        
      }else{
        vector<int>::iterator it = lower_bound(hana.begin(),hana.end(),ba);
        if( it==hana.end() )ba=0;
        else{
          ba = *it;
          hana.erase( it );
        }
      }
      turn ^= 1;
    }

    printf("%d\n%d\n",hana.size(),taro.size());
  }
  return 0;
}



0524

普通に探索するだけ

#include <iostream>
int main()
{
  int n,m;
  int seiza[200][2];
  int point[1000][2];
  while(std::cin>>n,n){
    for(int i=0; i<n; i++)
      std::cin>>seiza[i][0]>>seiza[i][1];
    std::cin>>m;
    for(int i=0; i<m; i++)
      std::cin>>point[i][0]>>point[i][1];
      
    for(int i=0; i<m; i++){
      int j;
      int dx = point[i][0] - seiza[0][0];
      int dy = point[i][1] - seiza[0][1];
      for(j=1; j<n; j++){
        int x = seiza[j][0] + dx;
        int y = seiza[j][1] + dy;
        int k;
        for(k=0; k<m; k++)
          if( point[k][0]==x && point[k][1]==y )break;
        if( k==m )break;
      }
      if( j==n ){
        printf("%d %d\n",dx,dy);
        break;
      }
    }
  }
  return 0;
}



0525

縦が最大10行なので、ビットで処理した。
このコードだと最大計算量は1024*10000*10なので最大ケースを試すと手元の環境では7secになる。
でも、AOJにsubmitすると0.5sec以内に終わった。AOJのデータセットはやさしいのかも。

#include <iostream>
#include <cstring>
using namespace std;
int main()
{
  int R,C;
  int field[10000];
  
  while(cin>>R>>C,R|C){
    memset(field,0,sizeof(field));
    for(int i=0; i<R; i++){
      for(int j=0; j<C; j++){
        int a; cin>>a;
        field[j] = (field[j]<<1) | a;
      }
    }
    
    int ans = 0;
    
    for(int k=1; k<(1<<R); k++){
      int sum = 0;
      for(int i=0; i<C; i++){
        int t1 = field[i];
        int t2 = ~field[i];
        int sum1 = 0;
        int sum2 = 0;
        for(int j=1; j<(1<<R); j<<=1){
          if( k&j ){
            sum1 += ( ((~t1)&j)==j ? 1 : 0 );
            sum2 += ( ((~t2)&j)==j ? 1 : 0 );
          }else{
            sum1 += ( (t1&j)==j ? 1 : 0 );
            sum2 += ( (t2&j)==j ? 1 : 0 );
          }
        }
        sum += max(sum1,sum2);
      }
      ans = max(ans,sum);
    }
    
    printf("%d\n",ans);
  }
  return 0;
}



0526

ダイクストラった。
優先度付きキューを使ってみた。

#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
#include <queue>
#include <functional>
using namespace std;
int main()
{
  int n,k;
  int node[101][101];
  while(cin>>n>>k,n|k){
  
    for(int i=0; i<=n; i++)
      for(int j=0; j<=n; j++)
        node[i][j] = INT_MAX;
    
    while(k--){
      int m;
      cin>>m;
      if( m ){
        int c,d,e;
        cin>>c>>d>>e;
        node[c][d] = node[d][c] = min(node[d][c],e);
      }else{
        int a,b;
        cin>>a>>b;
        int memo[101];
        priority_queue< pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > pq;
        for(int i=0; i<=n; i++)memo[i]=INT_MAX;
        pq.push(make_pair(0,a));
        memo[a]=0;
        while( !pq.empty() ){
          pair<int,int> pi = pq.top();
          if( pi.second == b )break;
          pq.pop();
          for(int i=1; i<=n; i++){
            if( node[pi.second][i]!=INT_MAX &&
               node[pi.second][i]+pi.first < memo[i] ){
              memo[i] = node[pi.second][i] + pi.first;
              pq.push(make_pair(memo[i],i));
            }
          }
        }
        printf("%d\n",memo[b]==INT_MAX?-1:memo[b]);
      }
    }
  }
  return 0;
}