看的别人的思路:
首先我们从最初的状态移到现在的状态,这样倒过来想。
然后我们肯定不会去移动最大的那一个,因为要移动最大的一个步数是把其他所有的移一遍的总和加1,然后就依次判断哪些是不在它应该在的地方,然后加上相应的步数。
其实是有点贪心的意思,倒过来的每一步都取最小值
AC代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
#define MOD 1000000
int step[100100];
int pos[100100];
void init(){
step[0] = 0;
for( int i = 1; i <= 100000; i++ ){
step[i] = ( 2 * step[i-1] + 1 ) % MOD;
}
}
int main(){
int num1, num2, num3;
int N;
init();
while( scanf( "%d", &N ) != EOF ){
scanf( "%d%d%d", &num1, &num2, &num3 );
for( int i = 1; i <= num1; i++ ){
int temp;
scanf( "%d", &temp );
pos[temp] = 1;
}
for( int i = 1; i <= num2; i++ ){
int temp;
scanf( "%d", &temp );
pos[temp] = 2;
}
for( int i = 1; i <= num3; i++ ){
int temp;
scanf( "%d", &temp );
pos[temp] = 3;
}
int posnow = pos[N];
int ans = 0;
for( int i = N; i >= 1; i-- ){
if( pos[i] != posnow ){
posnow = 6 - posnow - pos[i];//注意:将i移到题目所给的地方之后,i-1到了posnow的位置 之后就与这个新的posnow比较
ans = ( ans + step[i-1] + 1 ) % MOD;
}
}
cout << pos[N] << endl << ans << endl;
}
return 0;
}