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 跳房子