結果

問題 No.611 Day of the Mountain
ユーザー rickytheta
提出日時 2017-12-11 20:41:35
言語 C++11(廃止可能性あり)
(gcc 13.3.0)
結果
AC  
実行時間 207 ms / 2,017 ms
コード長 4,167 bytes
コンパイル時間 1,284 ms
コンパイル使用メモリ 164,464 KB
実行使用メモリ 5,248 KB
最終ジャッジ日時 2024-11-30 11:40:31
合計ジャッジ時間 2,662 ms
ジャッジサーバーID
(参考情報)
judge3 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 9
権限があれば一括ダウンロードができます
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:154:8: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  154 |   scanf("%d%d",&h,&w);
      |   ~~~~~^~~~~~~~~~~~~~
main.cpp:155:16: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  155 |   REP(i,h)scanf("%s",mp[i]);
      |           ~~~~~^~~~~~~~~~~~

ソースコード

diff #
プレゼンテーションモードにする

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef int _loop_int;
#define REP(i,n) for(_loop_int i=0;i<(_loop_int)(n);++i)
#define FOR(i,a,b) for(_loop_int i=(_loop_int)(a);i<(_loop_int)(b);++i)
#define FORR(i,a,b) for(_loop_int i=(_loop_int)(b)-1;i>=(_loop_int)(a);--i)
#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define DEBUG_VEC(v) cout<<#v<<":";REP(i,v.size())cout<<" "<<v[i];cout<<endl
#define ALL(a) (a).begin(),(a).end()
#define CHMIN(a,b) a=min((a),(b))
#define CHMAX(a,b) a=max((a),(b))
// mod
const ll MOD = 201712111ll;
#define FIX(a) ((a)%MOD+MOD)%MOD
int h,w;
char mp[353][353];
int dist[353][353];
bool pass[353][353];
bool canleft[353][353];
bool canup[353][353];
int dp[2][1<<18];
pii solve(){
if(h<w){
swap(h,w);
REP(i,353)REP(j,i)swap(mp[i][j], mp[j][i]);
}
assert(w <= 18);
// precalc
dist[0][0] = mp[0][0]=='?' ? 1 : mp[0][0]-'0';
REP(i,h)REP(j,w)if(i!=0 || j!=0){
dist[i][j] = 252521;
int c = mp[i][j]=='?' ? 1 : mp[i][j]-'0';
if(i>0)CHMIN(dist[i][j], dist[i-1][j]+c);
if(j>0)CHMIN(dist[i][j], dist[i][j-1]+c);
}
pass[h-1][w-1] = true;
REP(i,h)REP(j,w)canleft[i][j]=canup[i][j]=false;
FORR(i,0,h)FORR(j,0,w)if(i!=h-1 || j!=w-1){
pass[i][j] = false;
if(i<h-1){
int ni = i+1, nj = j;
int c = mp[ni][nj]=='?' ? 1 : mp[ni][nj]-'0';
if(dist[ni][nj]==dist[i][j]+c && pass[ni][nj]){
pass[i][j] = true;
canup[ni][nj] = true;
}
}
if(j<w-1){
int ni = i, nj = j+1;
int c = mp[ni][nj]=='?' ? 1 : mp[ni][nj]-'0';
if(dist[ni][nj]==dist[i][j]+c && pass[ni][nj]){
pass[i][j] = true;
canleft[ni][nj] = true;
}
}
}
// bit dp
REP(i,1<<w)dp[0][i] = 0;
dp[0][1] = 1;
REP(y,h)REP(x,w){
REP(i,1<<w)dp[1][i] = 0;
int del = ((1<<w)-1) ^ (1<<x);
int chk = 0;
if(canleft[y][x]){
chk |= 1<<(x-1);
}
if(canup[y][x] || y==0){
chk |= 1<<x;
}
REP(msk,1<<w){
int nbit = (msk & chk) > 0 && pass[y][x];
int nmsk = (msk & del) ^ (nbit << x);
dp[1][nmsk] = (dp[1][nmsk] + dp[0][msk]) % MOD;
}
if(mp[y][x]=='?'){
REP(msk,1<<w){
dp[1][msk&del] = (dp[1][msk&del] + dp[0][msk]*8 % MOD) % MOD;
}
}
REP(i,1<<w)dp[0][i] = dp[1][i];
}
int ans = 0;
REP(i,1<<w)if((i>>(w-1))&1){
ans = (ans + dp[0][i]) % MOD;
}
return pii(dist[h-1][w-1], ans);
}
int poy[353][353];
int d2[353][353];
int calc(){
d2[0][0] = poy[0][0];
REP(i,h)REP(j,w)if(i!=0 || j!=0){
d2[i][j] = 252521;
if(i>0)CHMIN(d2[i][j], d2[i-1][j]+poy[i][j]);
if(j>0)CHMIN(d2[i][j], d2[i][j-1]+poy[i][j]);
}
return d2[h-1][w-1];
}
pii naive(){
int n = h*w;
int mindist = 252521;
int ans = 0;
REP(msk,1<<n){
bool ok = true;
int mul = 1;
REP(i,h)REP(j,w){
int id = i*w+j;
if((msk>>id)&1){
if(mp[i][j]=='?'){
poy[i][j] = 1;
}else{
ok = false;
}
}else{
if(mp[i][j]=='?'){
poy[i][j] = 252;
mul = mul * 8 % MOD;
}else{
poy[i][j] = mp[i][j]-'0';
}
}
}
if(!ok)continue;
int ddd = calc();
if(ddd < mindist){
mindist = ddd;
ans = mul;
}else if(ddd == mindist){
ans = (ans + mul) % MOD;
}
}
return pii(mindist, ans);
}
int main(){
scanf("%d%d",&h,&w);
REP(i,h)scanf("%s",mp[i]);
pii ans = solve();
printf("%d\n%d\n",ans.first, ans.second);
// pii nai = naive();
// printf("%d %d\n",nai.first,nai.second);
return 0;
// while(true){
// h = 3;
// w = 3;
// REP(i,h)REP(j,w){
// int x = rand() % 14;
// if(x>=9){
// mp[i][j] = '?';
// }else{
// mp[i][j] = '1'+x;
// }
// }
// pii ans = solve();
// pii nai = naive();
// if(ans != nai){
// printf("%d %d\n",h,w);
// REP(i,h)puts(mp[i]);
// printf("ans : %d %d\n", ans.first, ans.second);
// printf("nai : %d %d\n", nai.first, nai.second);
// break;
// }
// }
return 0;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0