ICPC 国内予選2018B 折り紙 AOJ1625
シミュレーションやるだけ。折るたびに原点の座標を更新していけばよい。実装も重くないので楽。
#include <bits/stdc++.h> #define chmin(a, b) ((a)=min((a), (b))) #define chmax(a, b) ((a)=max((a), (b))) #define fs first #define sc second #define eb emplace_back using namespace std; typedef long long ll; typedef pair<int, int> P; typedef tuple<int, int, int> T; const ll MOD=1e9+7; const ll INF=1e18; int dx[]={1, -1, 0, 0}; int dy[]={0, 0, 1, -1}; int ori[1700][1700]; int main(){ int O[2]; int n,m,t,p; while(1){ cin >> n >> m >> t >> p; if(n == 0)break; for(int i = 0;i < 700;i++){ // 初期化 for(int j = 0;j < 700;j++){ ori[i][j] = 0; } } O[0] = 0; O[1] = 0; for(int i = 0;i < m;i++){ for(int j = 0;j < n;j++){ ori[O[0]+i][O[1]+j] = 1; } } for(int iii = 0;iii < t;iii++){ //折る動作 int d,c; cin >> d >> c; if(d == 1){ for(int i = 0;i < m;i++){ for(int j = 0;j < c;j++){ ori[O[0]+i][O[1]+j+(c-j-1)*2+1] += ori[O[0]+i][O[1]+j]; ori[O[0]+i][O[1]+j] = 0; } } O[1] += c; n = max(n-c,c); }else if(d == 2){ for(int j = 0;j < n;j++){ for(int i = 0;i < c;i++){ ori[O[0]+i+(c-i-1)*2+1][O[1]+j] += ori[O[0]+i][O[1]+j]; ori[O[0]+i][O[1]+j] = 0; } } O[0] += c; m = max(m-c,c); } } for(int ii = 0;ii < p;ii++){ int x,y; cin >> x >> y; cout << ori[O[0]+y][O[1]+x] << endl; } } }