2018美团CodeM编程大赛 初赛A轮 A 下棋(模拟)

本文介绍了一个关于在一维棋盘上移动棋子达到目标布局的算法问题。玩家需要通过移动棋子来匹配预设的目标布局,挑战在于找到达到目标所需的最小操作次数。文章提供了详细的解题思路及C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[编程|1000分] 下棋
时间限制:C/C++ 1秒,其他语言 2秒
空间限制:C/C++ 262144K,其他语言 524288K
64bit IO Format: %lld

题目描述

    有一个1*n的棋盘,上面有若干个棋子,一个格子上可能有多个棋子。
    你每次操作是先选择一个棋子,然后选择以下两个操作中的一个:
    (1) 若该棋子不在 (1,1),让这个棋子往左走一格,即从 (1,x) 走到 (1,x-1); 
    (2) 若该棋子不在 (1,n),且这个棋子曾经到达过(1,1),让这个格子往右走一格,即从 (1,x) 走到 (1,x+1)。
    给定一开始每个格子上有几个棋子,再给定目标局面每个格子上需要几个棋子,求最少需要多少次操作。

输入描述:

第一行一个正整数n表示棋盘大小。
第二行n个非负整数a_1, a_2, …, a_n 表示一开始 (1,i) 上有几个棋子。
第三行n个非负整数b_1, b_2, …, b_n 表示目标局面里 (1,i) 上有几个棋子。
保证 1 ≤ n ≤ 100,000,

输出描述:

输出一个非负整数,表示最少需要几次操作。
示例1

输入

5
0 0 1 1 0
1 0 0 0 1

输出

9

说明

先把(1,3)上的棋子走到(1,1),花费了2次操作。
然后把(1,4)上的棋子走到(1,1),再往右走到(1,5),花费了3+4=7次操作。
所以一共花了9次操作。

单纯的模拟。

代码实现:

#include<bits/stdc++.h>
#define sl(x) scanf("%lld",&x)
#define pl(x) printf("%lld\n",x)
using namespace std;
const int N = 1e6+5;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;
typedef long long ll;
char s[N];
map <char,int> mmp;
int main()
{
	int t,i,j,k;
	scanf("%d",&t);
	mmp['A'] = 1;mmp['B'] = 1;mmp['C'] = 1;
	mmp['D'] = 2;mmp['E'] = 2;mmp['F'] = 2;
	mmp['G'] = 3;mmp['H'] = 3;mmp['I'] = 3;
	mmp['J'] = 4;mmp['K'] = 4;mmp['L'] = 4; i = 5;
	mmp['M'] = i;mmp['N'] = i;mmp['O'] = i; i = 6;
	mmp['P'] = i;mmp['Q'] = i;mmp['R'] = i;mmp['S'] = i; i = 7;
	mmp['T'] = i;mmp['U'] = i;mmp['V'] = i; i = 8;
	mmp['W'] = i;mmp['X'] = i;mmp['Y'] = i;mmp['Z'] = i;
	while(t--)
	{
		scanf("%s",s);
		ll sum = 0;
		if(mmp[s[0]] == 1 || mmp[s[0]] == 3)
		sum = 1;
		else if(mmp[s[0]] == 2 || mmp[s[0]] == 4 || mmp[s[0]] == 6)
		sum = 2;
		else if(mmp[s[0]] == 5 || mmp[s[0]] == 7)
		sum = 3;
		else
		sum = 4;
		for(i = 0;s[i+1];i++)
		{
			ll t1 = mmp[s[i]],t2 = mmp[s[i+1]];
			ll c1 = t1/3,c2 = t2/3;
			ll a1 = t1%3,a2 = t2%3;
			if(c1 == c2)
			{
				sum += abs(a2-a1);
			}
			else if(abs(c1-c2) == 1)
			{
				sum += abs(a1-a2)+1;
			}
			else
			{
				sum += abs(a1-a2)+2;
			}
		}
		pl(sum);
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值