题意:
n个人坐成一圈,每个人绑起一只手,用L和R表示。如果一个R坐在L左边则会产生一个冲突。每次操作可将相邻两个人交换位置,求操作至冲突最少所需的最少次数。
题解:
如果只有L或只有R,则无冲突,否则冲突最小时是L连成一片,R连成一片,冲突为1.
可以单独考虑将L挪到一块去。枚举位置l,表示所有的L都向l挪,那么肯定一部分往后,一部分往前最优
可以找到一个位置r,l~r间的L往后,其它的往前,这样费用最小
对于l+1,新的r肯定也在原来的r后面(要考虑r从n-1变成0的情况),所以实际上就是维护两个指针而已
根据l和r的分开讨论就可以算出来了
其实我的代码还有问题,原本我是只考虑L的,现在是L和R各做一次取最小,否则过不了,不知道为什么,哪位高人看出来了请指点一下,感激不尽
import java.util.*;
public class LeftAndRightHandedDiv1
{
final int MAXN = 1000010;
long []psum=new long [MAXN];
int []lcnt=new int [MAXN];
long cal(int start,int num)
{
return (long)(start+start+num-1)*num/2;
}
boolean check(int r,int l,int n)
{
if(r>n) r=0;
int lnum=0,left;
if(r>=l)
lnum=lcnt[r]-lcnt[l-1];
else lnum=lcnt[n]-lcnt[l-1]+lcnt[r];
left=lcnt[n]-lnum;
return (r+n-l)%n-(lnum-1)<=(l+n-r-1)%n-(left-1);
}
long _countSwaps(String t,int n,char whi)
{
long ans=Long.MAX_VALUE;
lcnt[0]=0;
psum[0]=0;
for(int i=1;i<=n;++i)
{
lcnt[i]=lcnt[i-1];
psum[i]=psum[i-1];
if(t.charAt(i-1)==whi)
{
++lcnt[i];
psum[i]+=i;
}
}
if(lcnt[n]==n||lcnt[n]==0)
return 0;
int lnum=0,left=lcnt[n];
if(t.charAt(0)==whi)
{
++lnum;
--left;
}
for(int l=1,r=1;l<=n;++l)
{
while(check(r+1,l,n))
{
++r;
if(r>n)
r=1;
if(t.charAt(r-1)==whi)
{
++lnum;
--left;
}
if(left==0) break;
}
long tmp=0;
if(r>=l)
tmp+=(psum[r]-psum[l-1])-cal(l,lnum);
else tmp+=(psum[r]+(long)lcnt[r]*n)+(psum[n]-psum[l-1])-cal(l,lnum);
if(r>=l)
tmp+=cal(l+n-left,left)-(psum[n]-psum[r])-(psum[l-1]+(long)n*lcnt[l-1]);
else tmp+=cal(l-left,left)-(psum[l-1]-psum[r]);
ans=Math.min(ans, tmp);
if(t.charAt(l-1)==whi)
{
--lnum;
++left;
}
}
return ans;
}
public long countSwaps(String Y,int a,int b,int c,int d,int n)
{
long pre=a;
StringBuffer t=new StringBuffer();
for(int i=0;i<n;++i)
{
t.append(Y.charAt((int)pre%Y.length()));
pre=(pre*b+c)%d;
}
return Math.min(_countSwaps(t.toString(), n,'L'), _countSwaps(t.toString(), n,'R'));
}
public static void main(String []args)
{
LeftAndRightHandedDiv1 lef=new LeftAndRightHandedDiv1();
Scanner scan=new Scanner(System.in);
while(scan.hasNext())
{
String y=scan.next();
int a,b,c,d,n;
a=scan.nextInt();
b=scan.nextInt();
c=scan.nextInt();
d=scan.nextInt();
n=scan.nextInt();
System.out.println(lef.countSwaps(y, a, b, c, d, n));
}
scan.close();
}
}