Jeanny
寂兮,寥兮,独立不改,周行而不殆

P3955 图书管理员

 
P3956 棋盘
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int m,n,a[105][105], ans = 0x3fffffff, cnt, v[105][105], g[105][105];
int mvx[4] = {1,0,0,-1};
int mvy[4] = {0,1,-1,0};
void dfs(int x, int y, int c,int f,int sum){
  // cout<<"si "<<x<<" "<<y<<endl;
  if(sum > ans) return;
  if(sum >= g[x][y]) return;//等号千万不要漏!!!,不打等号只有70分,打了等号可以AC)
  if(x == m && y == m){
    if(sum < ans) ans = sum;
    return ;
  }
  g[x][y] = sum;
  for(int i = 0; i <= 3; i++){
    int xx = x + mvx[i];
    int yy = y + mvy[i];
    // cout<<"haha "<<xx<<" "<<yy<<" "<<v[xx][yy]<<endl;
    if(!v[xx][yy] && xx >= 1 && xx <= m && yy >= 1 && yy <= m){//枚举什么,合法方法是什么
      if(a[xx][yy] == -1 && f == 1) continue;//***error:return;
      if(a[xx][yy] != -1){//如果这一步是有颜色的,上一步用不用魔法都无所谓
          v[xx][yy] = 1;
          dfs(xx, yy, a[xx][yy], 0, sum + (a[xx][yy] == c ? 0:1) );
          v[xx][yy] = 0;//***add***
      }else{
        if(f == 0){//如果上一步不是无色,则是合法方法,枚举两种方案
          v[xx][yy] = 1;
          int tmp = sum + 2;//***不用分两种情况
          dfs(xx, yy, c, 1, tmp);
          v[xx][yy] = 0;
        }
      }
    }
  }
}
int x,y,c;
int main(){
  scanf("%d%d",&m,&n);
  memset(a,-1,sizeof a);
  memset(g,0x7f,sizeof g);
  for(int i = 1; i <= n; i++){
    scanf("%d%d%d",&x,&y,&c);
    a[x][y] = c;
  }
  if(m == 1 && a[1][1] != -1) {cout<<0<<endl;return 0;}
  if(m == 1 && a[1][1] == -1) {cout<<2<<endl;return 0;}
  v[1][1] = 1;
  dfs(1,1,a[1][1],0,0);//a[x][y]
  if(ans < 0x3fffffff)
    cout<<ans<<endl;
  else cout<<-1<<endl;
  return 0;
}
/*
2 3
1 1 0
1 2 0
2 1 1
2
*/
 // 9 9 10 9 color:0 0 f:0 0 sum:18 18
/*
7 16
1 1 1
1 3 1
2 6 0
2 4 1
3 6 1
4 4 0
4 7 1
4 3 1
5 7 1
5 5 0
5 6 1
6 5 0
6 1 1
7 6 0
7 7 0
7 2 1
*/

 

 
P3957 跳房子
posted on 2020-07-17 16:54  Jeanny  阅读(105)  评论(0)    收藏  举报