uva-101 && poj 1208 The Blocks Problem (模拟栈)
来源:互联网 发布:下载机械制图软件 编辑:程序博客网 时间:2024/06/06 15:50
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18191
题意: 下面的步骤看别人的,
機器手臂有以下幾種合法搬積木的方式(a和b是積木的編號):
move a onto b
move a over b
pile a onto b
pile a over b
quit
前四個動作中若a=b,或者a, b在同一堆積木中,那麼這樣的動作算是不合法的。所有不合法的動作應該被忽略,也就是對各積木均無改變
思路:就是一个模拟栈的问题,对自己还是有一点难度,折腾了几天,最后在poj找到测试数据,才摆脱re的折磨。基础差,各种差!!!
pile[i][i]表示第i堆第i个数,in[i]表示第i堆的总数,q[i]表示第i张牌的当前位置,模拟就好了,注意细节。
奉上一组poj上的测试数据:
9
move 4 onto 1
move 8 onto 3
move 7 onto 8
move 8 onto 1
move 2 onto 6
move 1 over 6
move 3 onto 7
move 8 onto 3
pile 2 onto 3
move 4 onto 5
move 6 onto 4
pile 3 onto 4
quit
#include <iostream>#include <cstdio>#include <cmath>#include <vector>#include <cstring>#include <string>#include <algorithm>#include <string>#include <set>#include <functional>#include <numeric>#include <sstream>#include <stack>#include <map>#include <queue>#define CL(arr, val) memset(arr, val, sizeof(arr))#define ll long long#define inf 0x7f7f7f7f#define lc l,m,rt<<1#define rc m + 1,r,rt<<1|1#define pi acos(-1.0)#define L(x) (x) << 1#define R(x) (x) << 1 | 1#define MID(l, r) (l + r) >> 1#define Min(x, y) (x) < (y) ? (x) : (y)#define Max(x, y) (x) < (y) ? (y) : (x)#define E(x) (1 << (x))#define iabs(x) (x) < 0 ? -(x) : (x)#define OUT(x) printf("%I64d\n", x)#define lowbit(x) (x)&(-x)#define Read() freopen("a.txt", "r", stdin)#define Write() freopen("dout.txt", "w", stdout);#define N 100005using namespace std;const int len = 100;int pile[len][len],in[len],q[len]; //pile[i][i]表示第i堆牌第i张,in表示第i堆牌总数,q表示第i张牌的当前位置int pd(int x,int y) //判断x跟y在不在同一堆{ if(q[x]==q[y]) return 1; //判断当前位置 是不是在同一堆即可 return 0;}void solve(int x) //将 x上的积木放回原来的位置 不包括x{ int i,ans,y,z; //从x这一堆 从上往下找 ans=in[q[x]]; //当前堆 积木总数 y=q[x]; //当前堆编号 for(i=ans;pile[y][i]!=x;i--) { z=pile[y][i]; //当前堆需要移动的积木编号 q[z]=z; //当前积木移到初始位置,那么 当前积木移动后当前位置变为自身编号 pile[z][++in[z]]=z; //重新存储 in[y]--; //当前堆减1 }}void solve2(int x,int y) //将 x本身和其上的积木一起放到y上,并且按顺序放{ int i,ans=0,z,y1,y2; for(i=in[q[x]];pile[q[x]][i]!=x;i--) { ans++; //求出x在当前堆的位置 } z=in[q[x]]; //当前堆 总数 y1=q[x];//当前堆 编号 for(i=z-ans;i<=z;i++) //移动 { q[pile[y1][i]]=q[y]; //把积木的当前位置改掉 pile[q[y]][++in[q[y]]]=pile[y1][i]; //移动 in[y1]--; //总数减 1 }}int main(){ //Read(); //文件读取 int n,i,j; char s[30],a[10],b[10]; int c,d; while(scanf("%d",&n)!=EOF) //读入n,代表有n张牌 { getchar(); CL(pile,0); //清空数组 CL(q,0); CL(in,0); for(i=0;i<n;i++) //初始化 { in[i]=1; q[i]=i; pile[i][1]=i; } while(1) { gets(s); if(s[0]=='q') break; sscanf(s,"%s %d %s %d",a,&c,b,&d); if(c==d||pd(c,d)) continue; if(strcmp(a,"move")==0) { if(strcmp(b,"onto")==0) { if(in[q[c]]>1)solve(c); if(in[q[d]]>1)solve(d); pile[q[d]][++in[q[d]]]=pile[q[c]][in[q[c]]--]; q[c]=q[d]; } else if(strcmp(b,"over")==0) { if(in[q[c]]>1) solve(c); pile[q[d]][++in[q[d]]]=pile[q[c]][in[q[c]]--]; q[c]=q[d]; } } else if(strcmp(a,"pile")==0) { if(strcmp(b,"onto")==0) { if(in[q[d]]>1)solve(d); solve2(c,d); } else if(strcmp(b,"over")==0) { solve2(c,d); } } } for(i=0;i<n;i++) { if(in[i]==0) { printf("%d:\n",i); } else { printf("%d:",i); for(j=1;j<=in[i];j++) { if(j!=in[i]) printf(" %d",pile[i][j]); else printf(" %d\n",pile[i][j]); } } } } return 0;}
下面是别人用vector写的,比我的规范多了!
#include <cstdio>#include <vector>#include <stack>using namespace std;const int MAXN = 30;vector<int> pile[MAXN];int pos[MAXN];const int MOVE = 0;const int PILE = 1;const int ONTO = 0;const int OVER = 1;void init(int n){ for(int i=0; i<n; i++){ pile[i].clear(); pile[i].push_back(i); pos[i] = i; }}bool ReadInstruct(int &insA, int &insB, int &x, int &y){ char s1[10]; scanf("%s", s1); if(s1[0] == 'q') return false; if(s1[0] == 'm') insA = MOVE; else insA = PILE; scanf("%d", &x); scanf("%s", s1); if(s1[1] == 'n') insB = ONTO; else insB = OVER; scanf("%d", &y); return true;}void PrintPile(int n){ for(int i=0; i<n; i++){ printf("%d:", i); for(int j=0; j<pile[i].size(); j++){ printf(" %d", pile[i][j]); } printf("\n"); }}void ReturnAbove(int x){ int px = pos[x]; while(1){ int y = pile[px].back(); if(y == x) break; pile[px].pop_back(); pile[y].push_back(y); pos[y] = y; }}void StoreAbove(stack<int> &stk, int x){ int px = pos[x]; while(1){ int y = pile[px].back(); pile[px].pop_back(); stk.push(y); if(y == x) break; }}void MoveTo(stack<int>& stk, int y) //move stk to y{ int py = pos[y]; while(!stk.empty()){ int x = stk.top(); stk.pop(); pos[x] = py; pile[py].push_back(x); }}int main(){ //freopen("in", "r", stdin); int n; scanf("%d", &n); init(n); int insA, insB, a, b; while(1){ if(ReadInstruct(insA, insB, a, b) == false) break; if(pos[a] == pos[b]) continue; if(insA == MOVE) //move ReturnAbove(a); if(insB == ONTO) //onto ReturnAbove(b); stack<int> stk; StoreAbove(stk, a); MoveTo(stk, b); } PrintPile(n);}
- uva-101 && poj 1208 The Blocks Problem (模拟栈)
- UVa-101 The Blocks Problem(栈模拟)
- POJ 1208 The Blocks Problem (UVA 101)
- uva 101 POJ 1208 The Blocks Problem 木块问题 vector模拟
- Uva 101 - The Blocks Problem//简单模拟
- Uva 101 - The Blocks Problem//简单模拟
- UVA 101 - The Blocks Problem(模拟)
- uva 101 The Blocks Problem(模拟)
- UVa 101 The Blocks Problem (超级模拟)
- uva 101 - The Blocks Problem(模拟)
- uva 101 The Blocks Problem (模拟)
- UVA 101 The Blocks Problem(模拟)
- UVa 101 The Blocks Problem [模拟]
- The Blocks Problem UVA 101 模拟
- uva 101 The Blocks Problem 模拟
- UVa 101 - The Blocks Problem 栈模拟 TLE
- uva 101 The Blocks Problem(模拟栈)
- POJ 1208 The Blocks Problem [模拟]
- Climbing Stairs
- Portal技术介绍
- android学习笔记-应用程序结构
- 百度坐标拾取
- 【Andord实战】SlideMenu+ViewPagerIndictor滑动侧边双栏+滑动导航栏
- uva-101 && poj 1208 The Blocks Problem (模拟栈)
- BZOJ 3744 Gty的妹子序列 分块+树状数组+可持久化线段树
- js对象创建的方式及其优势和不足2
- 欢迎您在新浪博客安家
- 飞思卡尔K60 FTM模块详…
- 飞思卡尔K60 FTM模块详…
- 微软借力.NET开源跨平台支持,布局物联网平台开发
- 主销后倾与主销内倾
- 飞思卡尔舵机学习笔记