Hatena::ブログ(Diary)

敗戦記

2011-04-15

PKU 1610 Quad Trees

http://poj.org/problem?id=1610

白黒の画像データを、同じ部分をまとめて符号化して出力するというような問題。

再帰

結構時間ギリギリでした

bool in[512][512];
map<int,vector<int> > ans;

void dfs(int x,int y,int n){
  set<bool> app;
  rep(i,n)rep(j,n)app.insert(in[x+i][y+j]);
  if(app.size()==1)ans[-n].pb(0),ans[-n].pb(*app.begin());
  else{
    ans[-n].pb(1);
    dfs(x,y,n/2);
    dfs(x,y+n/2,n/2);
    dfs(x+n/2,y,n/2);
    dfs(x+n/2,y+n/2,n/2);
  }
}

main(){
  int t;
  cin>>t;
  while(t--){
    ans.clear();
    int n;
    cin>>n;
    rep(i,n)rep(j,n)cin>>in[i][j];
    dfs(0,0,n);
    vector<int> vec;
    FOR(miter,ans)vec.insert(vec.end(),ALL(miter->S));
    reverse(ALL(vec));
    string out;
    rep(i,SZ(vec)){
      int p=0;
      rep(j,4){
        if(i+j<SZ(vec))p+=vec[i+j]<<j;
      }
      i+=3;
      if(p<9)out+=(p+'0');
      else out+=(p-10+'A');
    }
    reverse(ALL(out));
    cout<<out<<endl;
  }
}

PKU 1684 Dynamic Declaration Language (DDL)

http://poj.org/problem?id=1684

与えられたように簡易的な言語のようなものを実装する。

エラーコードの出力ミスで1WA

全く読みやすくないゴミソースになってます。

int toi(const string&in){
  int ret=0;
  rep(i,SZ(in))ret=ret*10+in[i]-'0';
  return ret;
}

main(){
  int test;
  cin>>test;
  rep(sc,test){
    cout<<sc+1<<endl;
    int n;
    cin>>n;
    cin.ignore();
    string in[n];
    rep(i,n){
      string temp;
      getline(cin,temp);
      rep(j,SZ(temp))if(temp[j]!=' ')in[i]+=temp[j];
    }
    map<int,PI> dec;
    rep(i,n){
      const string& str=in[i];
      if(str[1]=='='){
        int id=str[0];
        int num=toi(str.substr(2));
        if(dec.count(id))dec[id]=mp(num,1);
        else cout<<i+1<<' '<<2<<endl;
      }else if(str[0]=='G'){
        if(isalpha(str[4])){
          int id=str[4];
          int num=toi(str.substr(5));
          if(dec.count(id)){
            dec[id].S=1;
            if(dec[id].F>0)i=num-2;
          }else cout<<i+1<<' '<<2<<endl;
        }else{
          int num=toi(str.substr(4));
          i=num-2;
        }
      }else if(str[1]=='C'){
        int id=str[3];
        if(dec.count(id) && dec[id].S){
          dec[id]=mp(0,0);
        }else if(dec.count(id)){
          cout<<i+1<<' '<<1<<endl;
        }else dec[id]=mp(0,0);
      }else if(str[0]=='I'){
        if(dec.count(str[3]))dec[str[3]].F++,dec[str[3]].S=1;
        else cout<<i+1<<' '<<2<<endl;
      }else if(str[0]=='E'){
        break;
      }else if(str[0]=='D'){
        if(dec.count(str[3]))dec[str[3]].F--,dec[str[3]].S=1;
        else cout<<i+1<<' '<<2<<endl;
      }
    }
  }
}

PKU 2993 Emag eht htiw Em Pleh

http://poj.org/problem?id=2993

先程の問題の入出力を逆にするバージョン。

こちらのほうが微妙に楽な気がします。

これも書くだけ。

main(){
  vector<string> ans(17,string(33,' '));
  for(int i=0;i<17;i+=2){
    for(int j=0;j<33;j+=4){
      if(i)ans[i-1][j]='|';
      ans[i][j]='+';
      if(j){
        int x=i/2,y=j/4;
        rep(k,3){
          ans[i][j-k-1]='-';
          if(i && (x+y)%2)ans[i-1][j-k-1]='.';
          else if(i)ans[i-1][j-k-1]=':';
        }
      }
    }
  }
  rep(rp,2){
    string in;
    getline(cin,in);
    int pos;
    while(true){
      pos=in.find(',');
      if(pos==string::npos)break;
      in[pos]=' ';
    }
    stringstream ss(in.substr(7));
    while(ss>>in){
      char cc;
      if(SZ(in)==2)cc='P'+rp*('p'-'P');
      else cc=in[0]-rp*('P'-'p');
      int y=(in[SZ(in)-2]-'a')*4+2,x=(in[SZ(in)-1]-'1')*2+1;
      ans[x][y]=cc;
    }
  }
  reverse(ALL(ans));
  rep(i,17){
    cout<<ans[i]<<endl;
  }
}

PKU 2996 Help Me with the Game

http://poj.org/problem?id=2996

チェスボードを読み取ってそれぞれの駒の場所を出力するというような問題。

書くだけ。

いろいろと楽をしようと思ったけれど、あまり簡潔に書けてないです。

main(){
  map<char,set<PI> >ans;
  rep(i,17){
    string in;
    cin>>in;
    rep(j,SZ(in))
      if(isalpha(in[j])){
        if(isupper(in[j]))ans[in[j]].insert(mp(7-(i-1)/2+1,(j-2)/4+1));
        else ans[in[j]].insert(mp((i-1)/2-8,(j-2)/4+1));
      }
  }
  string out="KQRBNP";
  rep(re,2){
    if(!re)cout<<"White: ";
    else cout<<"Black: ";
    rep(i,SZ(out)){
      switch(toupper(out[i])){
      case 'R':
      case 'B':
        FOR(siter,ans[out[i]])cout<<','<<(char)toupper(out[i])<<char(siter->S+'a'-1)<<abs(siter->F);
        break;
      case 'P':
        FOR(siter,ans[out[i]])cout<<','<<char(siter->S+'a'-1)<<abs(siter->F);
        break;
      case 'K':
        FOR(siter,ans[out[i]])cout<<(char)toupper(out[i])<<char(siter->S+'a'-1)<<abs(siter->F);
        break;
      default:
        FOR(siter,ans[out[i]])cout<<','<<(char)toupper(out[i])<<char(siter->S+'a'-1)<<abs(siter->F);
        break;
      }
      out[i]=tolower(out[i]);
    }
    cout<<endl;
  }
}

PKU 2992 Divisors

http://poj.org/problem?id=2992

nCkの約数の個数を求める。(0<=k<=n<=431)

cinの遅さを改めて実感しました。

あと、高速化するのが大変でした。

素因数分解して事前計算して、頑張りました。

map<int,int> fac[432];
ll ans[432][432];

map<int,int> ret;
map<int,int> fact(int in){
  ret.clear();
  for(int i=2;i*i<=in;i++){
    if(in%i)continue;
    do{
      ret[i]++;
      in/=i;
    }while(in%i==0);
  }
  if(in>1)ret[in]++;
  return ret;
}

map<int,int> tt;
main(){
  rep(i,432){
    fac[i]=fact(i);
  }

  rep(n,432){
    tt.clear();
    rep(k,n+1){
      if(ans[n][min(k,n-k)])break;
      if(0<k)FOR(miter,fac[n-k+1])tt[miter->F]+=miter->S;
      FOR(miter,fac[k])tt[miter->F]-=miter->S;
      ll tans=1;
      FOR(miter,tt){
        tans*=miter->S+1;
      }
      ans[n][k]=tans;
    }
  }

  int n,k;
  while(~scanf("%d%d",&n,&k))cout<<ans[n][min(k,n-k)]<<endl;
}