HDU 4662 MU Puzzle 简单找规律

没有任何变换(III变U和删UU操作)之前,I 的个数一定是2^x个(也就是2的整数次幂)

若仅考虑III变U,那么设U的个数为k,I 的个数变为2^x-3*k

再加上删除UU操作,假设我们删除了2*n个U,设实际U的个数为cntU, 则k=cntU+2*n

设 I 的实际个数为cntI,cntI = 2^x - 3*(cntU+2*n), n有解的情况为:

( 2^x - 3*cntU - cntI ) % 6 == 0

只要找到一个x满足这个条件即可,不过要注意( 2^x - 3*cntU - cntI )>=0,因为 -6%6 = 0,之前没有判断这里,WA的很惨……

 1 #include <cstdio>

 2 #include <cstring>

 3 #include <cstdlib>

 4 #define LL long long int

 5 

 6 using namespace std;

 7 

 8 const int MAXN = 1000010;

 9 

10 LL cnt[30];

11 char str[MAXN];

12 LL bit[60];

13 

14 bool check()

15 {

16     LL I = cnt[ 'I' - 'A' ];

17     LL U = cnt[ 'U' - 'A' ];

18 

19     for ( int i = 0; i < 60; ++i )

20     {

21         if ( bit[i] - 3 * U - I >= 0 )

22         {

23             if ( ( bit[i] - 3 * U - I ) % 6 == 0 )

24                 return true;

25         }

26     }

27     return false;

28 }

29 

30 void init()

31 {

32     bit[0] = 1;

33     for ( int i = 1; i < 60; ++i )

34         bit[i] = ( bit[i - 1] << 1 );

35     return;

36 }

37 

38 int main()

39 {

40     init();

41     int T;

42     scanf( "%d", &T );

43     while ( T-- )

44     {

45         scanf( "%s", str );

46         int len = strlen(str);

47         memset( cnt, 0, sizeof(cnt) );

48         for ( int i = 0; i < len; ++i )

49             ++cnt[ str[i] - 'A' ];

50         if ( str[0] != 'M' || cnt[ 'M' - 'A' ] != 1 )

51         {

52             puts("No");

53             continue;

54         }

55         if ( check() ) puts("Yes");

56         else puts("No");

57     }

58     return 0;

59 }

 

你可能感兴趣的:(HDU)