nyoj 1187 模拟2048 (模拟题)

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=1187

模拟2048

时间限制:1000 ms  |  内存限制:65535 KB

难度:2

描述

单机手游2048的时代已经过去了,不过闲来无事的LN最近就是在写这个程序。

当然,这种事情他也希望大家能够参与其中。

那么问题来了,给你一个类比的2048 并告诉你方向,你能得出操作后的结果么?

输入
t组测试数据。

4*4的数据,类比游戏

q次询问。

1、2、3、4依次代表上、下、左、右。

输出
输出每次询问的结果。

每个数值字宽为5,默认右对齐。

每两组数据间一个空行

样例输入
1
64 256 256 4
64 4 4 64
0 64 128 64
16 8 0 16
2
3
2
样例输出
   64   512   4    0
   64    8   64    0
   64  128   64    0
   16    8   16    0

    0  512    0    0
   64    8    4    0
  128  128  128    0
   16    8   16    0
提示
此题为2048加强版:

如 有一行为 32 16 16 0 则向右结果为 0 0 0 64 向左结果为 32 32 0 0 。

即:合并后如果后面有可以合并的则合并 合并前的不算。

好久没写模拟题突然发现写起来好难...

注意提示。

分别写了4个函数,具体见代码吧,太长....

#include <iostream>
#include <cstdio>
using namespace std;
int map[5][5];
void push_up() {
	int i, j, k, num;
	for(i = 1; i <= 4; i++) {  //把0之外的数都移动到前面
		num = 0;
		for(j = 1; j < 4; j++) {
			if(map[j][i] == 0) {
				for(k = j; k < 4; k++) {
					map[k][i] = map[k + 1][i];
				}
				map[4][i] = 0;
				j--;  //移动过后,此元素可能还是0,所以还要再判断
				num++;  //r如果一列全是0,会死循环,因为最多只会移动4次,加个num记录次数可防止死循环
			}
			if(num > 4) break;
		}
	}
	for(i = 1; i <= 4; i++) {  //把数组合起来
		for(j = 1; j < 4; j++) {
			if(map[j][i] == map[j + 1][i] && map[j][i] != 0) {
				map[j][i] *= 2;
				for(k = j + 1; k < 4; k++) {
					map[k][i] = map[k + 1][i];
				}
				map[4][i] = 0;
				j--;
			}
		}
	}
}
void push_down() {
	int i, j, k, num;
	for(i = 1; i <= 4; i++) {
		num = 0;
		for(j = 4; j > 1; j--) {
			if(map[j][i] == 0) {
				for(k = j; k > 1; k--) {
					map[k][i] = map[k - 1][i];
				}
				map[1][i] = 0;
				j++;
				num++;
			}
			if(num > 4) break;
		}
	}
	for(i = 1; i <= 4; i++) {
		for(j = 4; j > 1; j--) {
			if(map[j][i] == map[j - 1][i] && map[j][i] != 0) {
				map[j][i] *= 2;
				for(k = j - 1; k > 1; k--) {
					map[k][i] = map[k - 1][i];
				}
				map[1][i] = 0;
				j++;
			}
		}
	}
}
void push_left() {
	int i, j, k, num;
	for(i = 1; i <= 4; i++) {
		num = 0;
		for(j = 1; j < 4; j++) {
			if(map[i][j] == 0) {
				for(k = j; k < 4; k++) {
					map[i][k] = map[i][k + 1];
				}
				map[i][4] = 0;
				num++;
				j--;
			}
			if(num > 4) break;
		}
	}
	for(i = 1; i <= 4; i++) {
		for(j = 1; j < 4; j++) {
			if(map[i][j] == map[i][j + 1] && map[i][j] != 0) {
				map[i][j] *= 2;
				for(k = j + 1; k < 4; k++) {
					map[i][k] = map[i][k + 1];
				}
				map[i][4] = 0;
				j--;
			}
		}
	}
}
void push_right() {
	int i, j, k, num;
	for(i = 1; i <= 4; i++) {
		num = 0;
		for(j = 4; j > 1; j--) {
			if(map[i][j] == 0) {
				for(k = j; k > 1; k--) {
					map[i][k] = map[i][k - 1];
				}
				map[i][1] = 0;
				j++;
				num++;
			}
			if(num > 4) break;
		}
	}
	for(i = 1; i <= 4; i++) {
		for(j = 4; j > 1; j--) {
			if(map[i][j] == map[i][j - 1] && map[i][j] != 0) {
				map[i][j] *= 2;
				for(k = j - 1; k > 1; k--) {
					map[i][k] = map[i][k - 1];
				}
				map[i][1] = 0;
				j++;
			}
		}
	}
}
int main() {
	int t;
	scanf("%d", &t);
	while(t--) {
		int i, j, k;
		for(i = 1; i <= 4; i++) {
			for(j = 1; j <= 4; j++) {
				scanf("%d", &map[i][j]);
			}
		}
		int q;
		scanf("%d", &q);
		int op;
		for(i = 0; i < q; i++) {
			scanf("%d", &op);
			if(op == 1) push_up();
			else if(op == 2) push_down();
			else if(op == 3) push_left();
			else push_right();
			for(j = 1; j <= 4; j++) {
				for(k = 1; k <= 4; k++) {
					printf("%5d", map[j][k]);
				}
				printf("\n");
			}
			if(i != q - 1) printf("\n");
		}
	}
	return 0;
}
时间: 2024-08-02 10:15:37

nyoj 1187 模拟2048 (模拟题)的相关文章

android 模拟2048

利用节日休息时间在ANDROID上进行学习并模拟2048游戏. 效果如下图: 制作思路: 1.画出2048游戏主界面,根据手机屏幕宽高度进行计算并画出每个方块的大小. 1 @Override 2 protected void onSizeChanged(int w, int h, int oldw, int oldh) { 3 super.onSizeChanged(w, h, oldw, oldh); 4 int cW = (Math.min(w, h) - 10) / 4; 5 6 addC

模拟 --- 搜索模拟

Robot Motion Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 10130   Accepted: 4932 Description A robot has been programmed to follow the instructions in its path. Instructions for the next direction the robot is to move are laid down in

MFC中热键&模拟键盘&模拟鼠标的使用

1. 热键的使用 热键不用了的话一定要卸载,否则下次启动时会被占用. 函数原型 注册函数 BOOL RegisterHotKey( HWND hWnd, // handle to window int id, // hot key identifier UINT fsModifiers, // key-modifier options UINT vk // virtual-key code ); hWnd------窗口句柄: id------热键的标识:(如果是exe 这个标识的范围就在0-4

火灾动态模拟消防模拟软件Thunderhead.Engineering.PyroSim.v2015.3.0810.Win64 1CD

火灾动态模拟消防模拟软件Thunderhead.Engineering.PyroSim.v2015.3.0810.Win64 1CD消防员3D立体定位追踪系统Seer3D v2.10 1CDPyroSim对于火灾动态模拟器(FDS)的图形用户界面.它被用来创建模拟火灾在火灾的准确预测烟气运动,温度和浓度的毒素.PyroSim为FDS和Smokeview的一个图形用户界面.一些PyroSim的主要功能包括:- 新的3D几何体创建和编辑工具.- 集成执行官方NIST版本FDS和Smokeview的的

驱动级模拟驱动级模拟:直接读写键盘的硬件端口!

驱动级模拟驱动级模拟:直接读写键盘的硬件端口! 有一些使用DirectX接口的游戏程序,它们在读取键盘操作时绕过了windows的消息机制,而使用DirectInput.这是因为有些游戏对实时性控制的要求比较高,比如赛车游戏,要求以最快速度响应键盘输入.而windows消息由于是队列形式的,消息在传递时会有不少延迟,有时1秒钟也就传递十几条消息,这个速度达不到游戏的要求.而DirectInput则绕过了windows消息,直接与键盘驱动程序打交道,效率当然提高了不少.因此也就造成,对这样的程序无

模拟2048(nyoj 1187)

模拟题, 提示 此题为2048加强版: 如 有一行为 32 16 16 0 则向右结果为 0 0 0 64 向左结果为 32 32 0 0 . 即:合并后如果后面有可以合并的则合并 合并前的不算. 这是题目的提示,按照要求做就行. 思路:举例向右划,那么从最右 i 向左扫,扫到一个数若与 i 位置的数相等,则i位置加上该数,继续向左扫,直到结束或者碰到一个数与 i 位置的数不相等.扫完后把数全归到最右端即可. #include<iostream> #include<stdio.h>

模拟赛 模拟题

1.送分题(ptgiving.cpp/c/pas) [问题背景] ? 众所周知, xkj是GH的得意门生,可是 xkj的数学成绩并不是很理想,每次GH在批评完数学限训做的差的人后,总会在后面加上一句,咱们班还有一位做的最差的同学--xkj,你看看你还有对号吗,居然比cdy做得还差! xkj当然是不服的啦,当场跟GH van♂硬币.在玩完硬币后,生成了一系列随机的乱七八糟的数字,并把他们整列成科学计数法的形式,并排序成有序的序列,还计算出排序的最小成本之后,终于,从桌堂里掏出了一本古老的小黄书--

离散事件模拟-银行管理(模拟题,队列)

离散事件模拟-银行管理 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 现在银行已经很普遍,每个人总会去银行办理业务,一个好的银行是要考虑 平均逗留时间的,即: 在一定时间段内所有办理业务的人员逗留的时间的和/ 总的人数.逗留时间定义为 人员离开的时间减去人员来的时间.银行只有考虑了这一点,我们在办理业务的时候,才不会等太多的时间. 为了简化问题,我们认为银行只有一号窗口和二号窗口可以办理业务 ,并且在时间范围是12<=tim

大数乘法——2016开发实习生腾讯模拟笔试编程题

给出两个大数,用字符串模拟整型数字的乘法. #include<iostream> #include<string> using namespace std; char* MultiString(char* str1,char* str2){ int len1=strlen(str1),len2=strlen(str2); if(len2>len1){ //len1,str1对应较长的字符串 char* temp=str1; int temp1=len1; str1=str2;