【51nod】1936 反转圈圆

1936 反转圈圆

有N盆花围成一圈,编号从0到(N-1)。第i(0<=i<N)号的左边是第((i+1)%N)号,右边是((i-1+N)%N)号。现在可以对任意相邻的两盆花交换位置,经过若干次交换之后,要求第i(0<=i<N)号的右边是第((i+1)%N)号,左边是((i-1+N)%N)号。请问最少要交换几次。

输入

多组测试数据。
第一行给出一个整数T(1<=T<=100),表示测试数据的数目。
接下来T行,每行给出一个整数N(1<=N<=1000000)。

输出

对于每一个测试数据,输出最少的交换次数。

输入样例

样例输入1

2
5
10

输出样例

样例输出1

4
20

最近开始复习算法(应该算是学习算法及其思想),从贪心开始,进入51nod,找到贪心就是这个题,左思右想,用找规律去做。

  • 首先发现的是0 4 3 2 1----->0 1 2 3 4,那么,只要挨个的把i和n-i进行交换位置就行了,也就是说,分为奇偶两种情况,n为偶数的时候,中间位置的数不用交换,多次例举并找规律有了ver 1.0的代码
    ver 1.0
#include <bits/stdc++.h>
using namespace std;

int main() { 
	int n,k=1,t;
	long long step;
	cin>>t;
	while(k<=t){
		cin>>n;
		if(n%2==0){
			step=0;
			for(int i=1;i<n/2;i++){
				int j=n-i;
				int minx= min(j-i+1,i+1+n-j);
//				cout<<minx<<"\n";
				step += 2*minx-3;
			}
		}
		else{
			step=0;
			for(int i=1;i<=n/2;i++){
				int j=n-i;
				int minx=min(j-i+1,i+1+n-j);
//				cout<<minx<<"\n";
				step += 2*minx-3;
			}
		}
		cout<<"::"<<step<<"\n";
		k++;
	}

	return 0;
}

多次检查,兴致勃勃的提交
WTF

WTF?!

再来几次检查修改,还是无果,去寻求寝室大佬,发现忽略了一个重要条件,循环的!也就是说
5 4 3 2 1 0 11 10 9 8 7 6
转换为
6 7 8 9 10 11 0 1 2 3 4 5
再寻一次规律,恍然大悟,就有了ver 2.0
ver 2.0

#include<stdio.h>

int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		int n;
		scanf("%d",&n);
		if(n&1) printf("%lld\n",1LL*(n-1)*(n-1)/4);
		else printf("%lld\n",1LL*n*(n-2)/4);
	}
}

室友提供的参考里,n为奇数的时候,输出1LL*(n/2)*(n/2),个人觉得不好推,就用了自己规律总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值