*問91 Blur 布の色の濃さのデータからどのように染料がたらされたのか逆算する問題。 解法 地道に一マスずつ動的計画法を適用しました。 コードはマトリックス化して配列にしておくべきだったかも。 めんどくさいので解説とか書かない。 #include<stdio.h> #include<vector> #include<set> struct S{ int n,x,y; int map[10][10]; std::vector<int> ansXs,ansYs,ansSize; bool operator<(const S& s)const{ if(n!=s.n)return n<s.n; if(y!=s.y)return y<s.y; if(x!=s.x)return x<s.x; for(int i=-2;i<=2;i++){ int dy=y+i; if(0<=dy&&dy<=9){ for(int x=0;x<=9;x++){ if(map[dy][x]!=s.map[dy][x])return map[dy][x]<s.map[dy][x]; } } } return false; } void commit(int size){ ansXs.push_back(x); ansYs.push_back(y); ansSize.push_back(size); } void commitPop(){ ansXs.pop_back(); ansYs.pop_back(); ansSize.pop_back(); } bool isNextOK(){ if(y<2)return true; if(2<=y&&y<=7){ return map[y-2][x]==0; } if(y==8){ if(map[y-2][x]>0)return false; if(x==9){ return n==0&&(map[y-1][x] | map[y][x] | map[y+1][x] | map[y-1][x-1] | map[y][x-1] | map[y+1][x-1])==0; }else if(x>0){ return (map[y-1][x-1] | map[y][x-1] | map[y+1][x-1])==0; }else{ return true; } } return false; } bool isS_OK(){ if(n<=0)return false; if(0<x&&x<9&&0<y&&y<9){ return map[y-1][x]>0 && map[y+1][x]>0 && map[y][x+1]>0 && map[y][x-1]>0 && map[y][x]>0; }else{ return false; } } bool isM_OK(){ if(0<x&&x<9&&0<y&&y<9){ bool t =map[y-1][x-1]>0 && map[y-1][x+1]>0 && map[y+1][x+1]>0 && map[y+1][x-1]>0; return t&&isS_OK(); }else{ return false; } } bool isL_OK(){ if(1<x&&x<8&&1<y&&y<8){ bool t =map[y-2][x]>0&&map[y+2][x]>0&&map[y][x+2]>0&&map[y][x-2]>0; return t&&isM_OK(); }else{ return false; } } void changeS(int add){ map[y-1][x]+=add; map[y+1][x]+=add; map[y][x-1]+=add; map[y][x+1]+=add; map[y][x]+= add; n+=add; } void changeM(int add){ map[y-1][x-1]+=add; map[y-1][x+1]+=add; map[y+1][x-1]+=add; map[y+1][x+1]+=add; changeS(add); } void changeL(int add){ map[y+2][x]+=add; map[y-2][x]+=add; map[y][x+2]+=add; map[y][x-2]+=add; changeM(add); } }; void searchS(std::set<S>& next,S& s1){ if(s1.isS_OK()){ s1.changeS(-1); s1.commit(1); searchS(next,s1); if(s1.isNextOK()==true){ next.insert(s1); } s1.commitPop(); s1.changeS(1); } } void searchM(std::set<S>& next,S& s1){ searchS(next,s1); if(s1.isM_OK()){ s1.changeM(-1); s1.commit(2); searchM(next,s1); if(s1.isNextOK()==true){ next.insert(s1); } s1.commitPop(); s1.changeM(1); } } void searchL(std::set<S>& next,S &s1){ searchM(next,s1); if(s1.isL_OK()){ s1.changeL(-1); s1.commit(3); searchL(next,s1); if(s1.isNextOK()==true){ next.insert(s1); } s1.commitPop(); s1.changeL(1); } } void calc(S seed){ std::set<S>::iterator it; S s1; std::set<S> memo,next; memo.insert(seed); for(int y=1;y<=8;y++){ for(int x=1;x<=9;x++){ for(it=memo.begin();it!=memo.end();it++){ s1=(*it); s1.x=x; s1.y=y; searchL(next,s1); if(s1.isNextOK())next.insert(s1); } memo.clear(); memo.insert(next.begin(),next.end()); next.clear(); } } it=memo.begin(); s1=(*it); for(int i=0;i<s1.ansXs.size();i++){ printf("%d %d %d\n",s1.ansXs[i],s1.ansYs[i],s1.ansSize[i]); } } int main(){ S seed; scanf("%d",&seed.n); for(int i=0;i<10;i++){ for(int j=0;j<10;j++){ scanf("%d",&seed.map[i][j]); } } calc(seed); }