列表

详情


NC216209. PassThroughWithOneBreath

描述

众所周知,一气通贯是日本麻将中的一种和牌形式。不会麻将的看到了《神様になった日》里面的一气通贯觉得非常的帅啊。所以他想让你帮他把一副头尾相连的牌变成一气通贯的形式。
理解的一气通贯是一个从小到大顺时针排好的顺子(顺子是指连续的数字),顺子的头部可以从任何位置开始(例如2 3 4 5 和 4 5 2 3 这样的牌面都是一个以2为头的一气通贯的顺子),注意顺子是可以从负值开始的。
            
                        如图为一副0 1 -2 -1的一气通贯牌型。
现在给你一副头尾相连的牌,有如下两类操作:
  • 一次操作将一张牌的牌面减
  • 一次操作将一张牌的牌面加
请问最少需要多少次操作,你能够把这幅牌变成一气通贯的形式。

输入描述

第一行给出一个正整数,表示共有T组测试数据。
对于每组测试数据第一行给出一个正整数 个整数输入保证所有的总和小于等于
第二行按顺时针给出个数字,第个数字表示第张牌的牌面,第张牌和第张牌相连,第张牌的牌面值

输出描述

输出包含行,每行包含一个整数,表示将第组牌变成一气通贯牌所需要的最少操作次数。

示例1

输入:

2
3
2 3 3
5
5 3 1 4 6

输出:

1
5

说明:

样例中第一组最少操作次数达到的一种牌面是2 3 4,共需1{}次。
样例中第二组最少操作次数达到的一种牌面是6 2 3 4 5,共需5{}次。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 30ms, 内存消耗: 376K, 提交时间: 2020-12-28 16:25:50

#include<bits/stdc++.h>
using namespace std;
long long a[10000],b[10000],ans;
int main(void){
	
	long long j,sum,y,i,t,n,x;
	scanf("%lld",&t);
	while(t--){
		
		sum=1e16;
		scanf("%lld",&n);
		for(i=1;i<=n;i++){
			
			scanf("%lld",&a[i]);
			a[i+n]=a[i];
		}
		for(i=1;i<2*n;i++){
			
			y=a[i]-i;
			for(j=1;j<2*n;j++){
				
				b[j]=b[j-1]+abs(a[j]-y-j);
				if(j>=n) sum=min(sum,b[j]-b[j-n]);
			}
		}
		printf("%lld\n",sum);
	}
}

上一题